【问题标题】:Wrap link <a> around <div>将链接 <a> 包裹在 <div> 周围
【发布时间】:2021-07-11 06:58:31
【问题描述】:

是否可以像这样在&lt;div&gt;s 周围包裹&lt;a&gt; 标签:

<a href=etc etc>
    <div class="layout">
        <div class="title">
        Video Type
            <div class="description">Video description</div>
        </div>
    </div>
</a>

Eclipse 告诉我 div 的位置不对? 如果这是不允许的。如何使整个“布局”类成为链接?

【问题讨论】:

    标签: javascript html anchor


    【解决方案1】:

    这种结构在 HTML5 中是有效的,因为在 HTML5 中,锚点几乎可以包裹任何元素,除了其他锚点和表单控件。现在大多数浏览器都支持这一点,并将问题中的代码解析为有效的 HTML。下面的答案写于 2011 年,如果您支持旧版浏览器(*cough* Internet Explorer *cough*),它可能会很有用。


    没有 HTML5 解析器的旧版浏览器(比如 Firefox 3.6)仍然会对此感到困惑,并且可能会弄乱 DOM 结构。

    HTML4 的三个选项 - 使用所有内联元素:

    <a href=etc etc>
        <span class="layout">
            <span class="title">
            Video Type
                <span class="description">Video description</span>
            </span>
        </span>
    </a>
    

    然后用display: block设置样式


    使用 JavaScript 和:hover

    <div class="layout">
        <div class="title">
        Video Type
            <div class="description">Video description</div>
        </div>
    </div>
    

    和(假设 jQuery)

    $('.layout').click(function(){
        // Do something
    }):
    

    .layout:hover {
        // Hover effect
    }
    

    或者最后使用绝对定位放置一个a的锚点,用CSS覆盖整个.layout

    <div class="layout">
        <div class="title">
        Video Type
            <div class="description">Video description</div>
        </div>
        <a class="more_link" href="somewhere">More information</a>
    </div>
    

    还有 CSS:

    .layout {
        position: relative;
    }
    
    .layout .more_link {
        position: absolute;
        display: block;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        text-indent: -9999px;
        z-index: 1000;
    }
    

    当然,这不适用于旧版本的 IE。

    【讨论】:

    【解决方案2】:

    虽然&lt;a&gt; 标记不允许包含&lt;div&gt; 元素,但允许包含其他内联元素,例如&lt;span&gt;

    当我遇到问题时,我将 div 标签换成了&lt;span&gt;。由于 span 标签是一个内联元素,因此您需要将 display:block 应用于您的 &lt;span&gt; 元素的 css,以使其行为类似于 &lt;div&gt; 块元素。 这应该是有效的 xhtml,并且不需要任何 javascript。

    这是一个例子:

    <a href="#">
        <span style="display:block">
            Some content. Maybe some other span elements, or images.
        </span>
    </a>
    

    【讨论】:

      【解决方案3】:

      另一个简单的解决方案 - 只需向 div 添加一个 onclick 事件处理程序:

      <div class="layout" onclick="location.href='somewhere'">
          <div class="title">
          Video Type
              <div class="description">Video description</div>
          </div>
      </div>
      

      这对我很有用,但有一个小问题。我不确定这对搜索引擎有多友好。我担心谷歌的网络爬虫可能找不到这个链接,所以我也倾向于在块的某处包含一个传统的 HREF 链接,如下所示:

      <div class="layout" onclick="location.href='destination_url'">
          <div class="title">
          Video Type
              <div class="description">Video description</div>
          </div>
          <a href="destination_url">This is a link</a>
      </div>
      

      【讨论】:

        【解决方案4】:

        Timothy 的解决方案是正确的...而不是在 div 周围包裹锚...您只需使用 display:block 为锚元素提供布局并添加锚的大小和宽度...

        .div_class   { width: 100px; height: 100px; }
        .div_class a { width: 100px; height: 100px; display: block; }
        
        <div class='div_class'><a href="#"></a></div> 
        

        【讨论】:

          【解决方案5】:

          HTML 提供了两种通用元素,其中div自然 块元素,span自然 内联元素。所有其他元素都被类似地分配为 natural 块或内联。

          现在,虽然两者都可以通过 css display 设置为 inlineinline-blockblock 中的任何一个,但它们仍然被视为它们的自然自我,因此警告信息。豹子和斑点之类的东西。

          然而,css 仅用于制作元素 看起来 的样子(表示),但实际上并不是 的样子(功能),所以它不改变元素的基本性质,尽管这在实践中变得非常模糊。一个span 变成了block 变成了一个恶霸,将其他一切都踢下线,这是非常不@inline 的行为。

          因此,为了减轻他们的自然行为和css引起的行为之间可能发生的冲突,最好允许:

          • div 或任何 natural 块标记只能是 blockinline-block
          • span 或任何 自然 内联标签只能是 inlineinline-block

          这也将减轻倾向于构建可能最终会产生错误和警告消息的页面结构。

          基本上,永远不要在 natural 内联标签内嵌入任何深度的 natural 块标签。

          之所以存在真正的区别,可能是因为最初设想 HTML 时的用途过于简单。

          当然,框架制造商通过在任何地方使用无数的divs 解决了很多这些嵌入内容的问题,并且“divitis”诞生了,并且在每个框架中仍然存在并且运行良好。只需在几乎所有商业网页上的浏览器中按F12 并向下钻取十几个divs。这个页面有 15 个完整的divs 级别。

          不难看出为什么选择divs 是有道理的。例如,p 标记可能有一堆指向不同站点的链接,这没关系,因为在块 p 中允许内联链接。但是,如果不想在这些 url 中显示查询变量,则需要 buttons。如果只有一个,那么p 可以放在form 中,因为p 不能包含form

          按钮上的formaction 属性可用于定位非默认表单的url,但它仍然不允许独立的表单,每个表单都有自己的隐藏输入集。按钮可以使用form 属性将其与不是祖先的表单一起使用,但跟踪起来可能会很混乱。

          但是,要使指向不同站点的多个链接显示为一个段落的一部分,唯一的方法是使用div 而不是p,然后将每个button 包装在其自己的form 中设置为@ 987654354@。大多数框架必须应对如此复杂的场景,嵌套 divs 是唯一的出路。

          这意味着他们实际上只需要为每个目的管理一个标签,并将其作为一个孤立的环境进行管理。因此,本应偶尔使用的功能分组标签变成了网络的乐高积木。而且他们都不会冒险通过匆忙转换为 HTML5 语义标签来破坏他们的框架。最后,语义标签仅适用于相当静态的内容,而不适用于丰富的交互式网站。

          【讨论】:

            【解决方案6】:

            我曾尝试创建custom solution using jQuery,它会模仿与a 标记相同的行为,用于父DIV。

            演示: https://jsfiddle.net/kutec/m9vxhcke/

            根据 W3C 标准,您不能这样做:

            <div class="boxes">
                <a href="http://link1.com" target="_blank">
                    <div class="box">
                        <h3>Link with _blank attr</h3>
                    </div>
                </a>
            </div>
            

            你必须遵守这个:

            <div class="boxes">
                <div class="box">
                    <h3>
                        <a href="http://link1.com" target="_blank">Link with _blank attr</a>
                    </h3>
                </div>
            </div>
            

            但是按照上面的代码,你不会得到整个 DIV 的可点击 :)。

            正确的结构应该是这样的,它还允许您单击 DIV 以重定向给定的href

            <div class="boxes" data-href="http://link1.com" data-target="_blank">
                <div class="box">
                    <h3>
                        <a href="http://link1.com" target="_blank">Link with _blank attr</a>
                    </h3>
                </div>
            </div>
            

            简单解决方案

            $(function() {  
                $('.boxes a').each(function(){
                    var aTag = $(this).attr('href');
            
                    $(this).parent().attr('data-href',aTag);        
            
                    $("[data-href]").click(function() {
                        window.location.href = $(this).attr("data-href");
                        return false;
                    });
                })  
            }(jQuery));
            

            动态解决方案

            (function ( $ ) { 
                $.fn.dataURL = function() {
            
                    // variables
                    var el = $(this);
                    var aTag = el.find('a');
                    var aHref;
                    var aTarget;
            
                    // get & set attributes
                    aTag.each(function() {
                        var aHref = $(this).attr('href');
                        $(this).parent().attr('data-href',this);
            
                        aTarget = $(this).attr('target');
                        $(this).parent().attr('data-target',aTarget);
                    });
            
                    // imitation - default attributes' behavior on "data-" attributes
                    $(el).delegate('[data-href]','click', function() {
                        var loc = window.location.href;
                        loc = $(this).attr("data-href");
                        aTarget = $(this).attr('data-target');
            
                        if(aTarget == "_blank"){
                            window.open(loc);
                        } else {
                            window.location = loc;
                        }
            
                        return false;
                    });     
            
                    //removing attributes from selector itself
                    el.removeAttr('data-href');
                    el.removeAttr('data-target');
            
                    // css
                    $('[data-href]').css('cursor','pointer');
                };
            }( jQuery ));
            

            最终通话

            <script>
                $('.boxes').dataURL();
            </script>
            

            希望这会有所帮助:)

            【讨论】:

            • 出于好奇,这对 SEO 和 Google bot 爬行有何公平?
            • @JohnBell,通过遵循此解决方案,您将模仿与 DIV 元素的 A 标记相同的行为。但是,我们不会从 A 标记中删除 HREF 属性,所以无论如何这里的 SEO 都不会受到干扰 :)
            • 是的,这是有道理的。谢谢。
            【解决方案7】:

            您只想将“a”标签设置为display: block;

            Eclipse 适当地告诉您您的 HTML 不符合规范(因为锚标记中不允许使用 div 标记)。

            但是,既然您似乎希望在视觉上使锚看起来像一个大盒子,那么只需将其设置为这样 :)

            【讨论】:

            • 将 div 放入 a 在技术上违反 HTML 规范。我还可以这样做吗?
            • 问题归结为“为什么”你使用 div 标签......如果它只是用于 JavaScript 目的的占位符或其他东西......只需使用显示块的 SPAN 标签(如果你想要块状)。
            • 另外,span 内不能有 h2,有什么解决办法吗?
            • 您可以在 div 中放置一个锚标记...使其成为 div 中的最后一个元素,并将其设置为显示块,并填充 100% 的宽度和高度(您可以需要指定高度)。然后让它“位置:绝对;”并有最外层的 div “位置:相对;” ...这是另一种可能对您有用的解决方案,但这一切都取决于您在做什么...如果不谈 30 分钟,我真的无法给出一个很好的解释 :)
            • 一般来说,你不能有一个内联元素,比如一个锚 () 或 span,环绕一个块级元素,比如一个分隔 (
              ) 或标题。跨度>
            【解决方案8】:

            使 div 成为链接/可点击的一种简单方法是使用 html javascript onclick 属性:

            &lt;div class="clickable-div" onclick="location.href='#';"&gt;&lt;div&gt; ... &lt;/div&gt;&lt;/div&gt; 

            【讨论】:

              猜你喜欢
              相关资源
              最近更新 更多
              热门标签