代码之家  ›  专栏  ›  技术社区  ›  Deeksy

活动子项的父项的复杂CSS选择器[重复]

  •  292
  • Deeksy  · 技术社区  · 16 年前

    http://drupal.org

    <ul class="menu">  
        <li>  
            <a class="active">Active Page</a>  
        </li>  
        <li>    
            <a>Some Other Page</a>  
        </li>  
    </ul>  
    

    为了清楚起见,我想对列表项应用样式,而不是锚定。

    10 回复  |  直到 13 年前
        1
  •  246
  •   BoltClock    12 年前

    According to Wikipedia :

    CSS无法选择满足特定条件的元素的父元素或父元素。更高级的选择器方案(如XPath)将支持更复杂的样式表。然而,CSS工作组拒绝父选择器建议的主要原因与浏览器性能和增量渲染问题有关。

    对于将来搜索的任何人来说,这也可能被称为祖先选择器。

    更新:

    Selectors Level 4 Spec 允许您选择select的哪一部分是主题:

    选择器的主题可以通过前缀显式标识 虽然选择器表示的元素结构是 相同,带或不带美元符号,表示本节中的主题 方法可以更改在该方法中表示主题的复合选择器 结构

    例1:

    有序列表:

    OL > LI:only-child
    

    但是,下面的一个表示具有唯一子级的有序列表,

    $OL > LI:only-child
    

    这两个选择器表示的结构相同, 但选择器的主题不是。

    尽管这在任何浏览器或jQuery中都不可用(目前,2011年11月)。

        2
  •  161
  •   Dave Ward    12 年前

    不幸的是,CSS无法做到这一点。

    // JavaScript code:
    document.getElementsByClassName("active")[0].parentNode;
    
    // jQuery code:
    $('.active').parent().get(0); // This would be the <a>'s parent <li>.
    
        3
  •  41
  •   David Clarke    7 年前

    聚会又迟到了,但无论如何,使用jQuery可能会更简洁一些。就我而言,我需要找到 <ul> 一个类的父标记 <span> <li> . jQuery具有 :has 选择器,以便可以通过其包含的子项来识别父项(根据@Afrowave的注释ref更新: https://api.jquery.com/has-selector/ ):

    $("ul").has("#someId")
    

    ul 某物 . 或者,为了回答最初的问题,应该使用以下类似的方法(未经测试):

    $("li").has(".active")
    
        4
  •  28
  •   Community Maksym Gontar    4 年前

    父选择器

    CSS4 ,当前W3C草案中最重要的消息是对父选择器的支持。

    $ul li:hover{
        background: #fff;
    }
    

    https://www.w3.org/TR/2011/WD-selectors4-20110929/#overview (最后一行)。

        5
  •  16
  •   Community Maksym Gontar    4 年前

    Selectors Level 4 概述了显式设置 主题 选择器的名称。这将允许OP使用选择器设置列表元素的样式 $li > a.active

    从…起 Determining the Subject of a Selector :

    OL > LI:only-child

    $OL > LI:only-child

    这两个选择器表示的结构相同,但选择器的主题不同。

    编辑:考虑到草案规范的“通风性”,最好通过检查 CSSWG's page on selectors level 4 .

        6
  •  6
  •   Matt Wagner    6 年前

    CSS4选择器的未来答案

    :has 伪选择器,它可能能够做这件事。

    li:has(a:active) {
      /* ... */
    }
    

    这个 browser support 关于这一点,目前基本上是不存在的,但目前正在考虑中 official specs .


    虽然CSS确实不能提升,但不能获取另一个元素的父元素是不正确的。让我重申:

    使用HTML示例代码,您可以在不指定li的情况下获取li

    ul * a {
        property:value;
    }
    

    在本例中,ul是某个元素的父元素,而该元素是锚点的父元素。使用此方法的缺点是,如果存在包含锚定的任何子元素的ul,它将继承指定的样式。

    也可以使用子选择器,因为无论如何都必须指定父元素。

    ul>li a {
        property:value;
    }
    

    所以,用密码回答你的问题。

    ul.menu > li a.active {
        property:value;
    }
    

    这应该抓取具有menu类的ul,以及仅包含具有active类的锚点的子列表项。

        7
  •  1
  •   Mark B    15 年前

    我对Drupal也有同样的问题。考虑到CSS的局限性,实现此功能的方法是在生成菜单HTML时向父元素添加“active”类。关于这一点,有一个很好的讨论 http://drupal.org/node/219804 ,其结果是,此功能已被引入到nicemenus模块的6.x-2.x版本中。由于这仍在开发中,我已经将补丁向后移植到了6.x-1.3 http://drupal.org/node/465738 这样我就可以继续使用模块的生产就绪版本。

        8
  •  1
  •   Arun thelatemail    11 年前

    jQuery 父类,但只是为了补充,我想分享一个快速的代码片段,用于将类添加到导航中,以便可以将样式添加到导航中 li 是的,我不知道。

    $("li ul").parent().addClass('has-sub');
    
        9
  •  1
  •   Igor Ivancha    8 年前

    .parent() jQuery选择器。我的问题是,我在使用 .parent .parent() . 我知道这是个愚蠢的错误。

    绑定事件(在本例中,由于我的选项卡处于模式,因此我需要将它们绑定到 .live .click .

    $('#testTab1 .tabLink').live('click', function() {
        $('#modal ul.tabs li').removeClass("current"); //Remove any "current" class
        $(this).parent().addClass("current"); //Add "current" class to selected tab
        $('#modal div#testTab1 .tabContent').hide();
        $(this).next('.tabContent').fadeIn();   
        return false;
    })
    $('#testTab2 .tabLink').live('click', function() {
        $('#modal ul.tabs li').removeClass("current"); //Remove any "current" class
        $(this).parent().addClass("current"); //Add "current" class to selected tab
        $('#modal div#testTab2 .tabContent').hide();
        $(this).next('.tabContent').fadeIn();   
        return false;
    })
    

    <div id="tabView1" style="display:none;">
      <!-- start: the code for tabView 1 -->
      <div id="testTab1" style="width:1080px; height:640px; position:relative;">
        <h1 class="Bold_Gray_45px">Modal Header</h1>
        <div class="tabBleed"></div>
        <ul class="tabs">
          <li class="current"> <a href="#" class="tabLink" id="link1">Tab Title Link</a>
            <div class="tabContent" id="tabContent1-1">
              <div class="modalCol">
                <p>Your Tab Content</p>
                <p><a href="#" class="tabShopLink">tabBased Anchor Link</a> </p>
              </div>
              <div class="tabsImg"> </div>
            </div>
          </li>
          <li> <a href="#" class="tabLink" id="link2">Tab Title Link</a>
            <div class="tabContent" id="tabContent1-2">
              <div class="modalCol">
                <p>Your Tab Content</p>
                <p><a href="#" class="tabShopLink">tabBased Anchor Link</a> </p>
              </div>
              <div class="tabsImg"> </div>
            </div>
          </li>
        </ul>
      </div>
    </div>
    

    当然,你可以重复这个模式,再加上更多的李

        10
  •  0
  •   ЯegDwight kri    12 年前

    我刚才想到的另一个想法可能是一个纯CSS解决方案。将活动类显示为绝对定位的块,并设置其样式以覆盖父li。

    a.active {
       position:absolute;
       display:block;
       width:100%;
       height:100%;
       top:0em;
       left:0em;
       background-color: whatever;
       border: whatever;
    }
    /* will also need to make sure the parent li is a positioned element so... */
    ul.menu li {
        position:relative;
    }    
    

    对于那些想在不使用jquery的情况下使用javascript的人。。。

    选择父对象很简单。你需要一个 getElementsByClass 函数,除非您可以让drupal插件为活动项分配ID而不是类。我提供的功能是从其他天才那里获得的。它工作得很好,只是在调试时请记住,该函数将始终返回一个节点数组,而不仅仅是一个节点。

    active_li = getElementsByClass("active","a");
    active_li[0].parentNode.style.whatever="whatever";
    
    function getElementsByClass(node,searchClass,tag) {
        var classElements = new Array();
        var els = node.getElementsByTagName(tag); // use "*" for all elements
        var elsLen = els.length;
        var pattern = new RegExp("\\b"+searchClass+"\\b");
        for (i = 0, j = 0; i < elsLen; i++) {
           if ( pattern.test(els[i].className) ) {
           classElements[j] = els[i];
           j++;
       }
    }
    return classElements;
    }