复杂的CSSselect器为活动的孩子的父母

有没有办法根据类中的子元素的类来select父元素? 与我有关的例子,这个例子涉及http://drupal.org的一个漂亮的菜单插件的HTML输出。 输出呈现如下所示:

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

我的问题是是否有可能将样式应用于包含具有活动类的锚的列表项。 显然,我宁愿列表项目被标记为活动,但我没有控制产生的代码。 我可以使用JavaScript来执行这种事情(jQuery的泉水脑海),但我想知道是否有一种方法来使用CSSselect器来做到这一点。

为了清楚起见,我想将样式应用于列表项目,而不是锚点。

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

JavaScript虽然不是很困难:

 // JavaScript code: document.getElementsByClassName("active")[0].parentNode; // jQuery code: $('.active').parent().get(0); // This would be the <a>'s parent <li>. 

根据维基百科 :

select器无法提升

CSS没有办法select满足特定条件的元素的父代或祖代。 更高级的select器scheme(如XPath)可以实现更复杂的样式表。 然而,CSS工作组拒绝父代select器提案的主要原因与浏览器性能和增量渲染问题有关。

而对于将来search的人来说,这也可能被称为祖先select器。

更新:

select器4级规范允许您select哪个部分的select是主题:

select器的主题可以通过向select器中的一个复合select器添加美元符号($)来显式识别。 尽pipeselect器代表的元素结构是相同的或者没有美元符号,这样指示主体可以改变哪个复合select器代表该结构中的主体。

例1:

例如,以下select器代表列表项目LI有序列表OL的唯一子项:

 OL > LI:only-child 

然而,下面的代表一个有秩序的列表OL有一个独特的孩子,那个孩子是一个LI:

 $OL > LI:only-child 

这两个select器所代表的结构是一样的,但select器的主体却不一样。

虽然目前还没有(目前,2011年11月)在任何浏览器或作为jQueryselect器。

晚会到了晚会,但为了什么是值得的是可能使用jQuery更简洁一点。 在我的情况下,我需要find包含在子<li>中的<span>标签的<ul>父标签。 jQuery有:hasselect器,所以可以通过它包含的子元素来标识一个父元素(更新每@ Afrowave的评论ref: https ://api.jquery.com/has-selector/):

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

将select具有id为someId的子元素的ul元素。 或者回答原来的问题,像下面这样的应该做的伎俩(未经testing):

 $("li").has(".active") 

“家长”select器

现在,没有select在CSS中select父元素(甚至没有CSS3)。 但在CSS4中 ,当前W3C草案中最重要的消息是对父代select器的支持。

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

使用上面的方法,当hover列表元素时,整个无序列表将通过添加一个白色背景来突出显示。

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

select器级别4的初稿概述了明确设置select器主题的方法。 这将允许OP使用select器$li > a.active设置列表元素的$li > a.active

从确定select主体 :

例如,以下select器代表列表项目LI有序列表OL的唯一子项:

OL > LI:only-child

然而,下面的代表一个有秩序的列表OL有一个独特的孩子,那个孩子是一个LI:

$OL > LI:only-child

这两个select器所代表的结构是一样的,但select器的主体却不一样。

编辑:鉴于规范草案的“drafty”如何,最好通过检查select器级别4上的CSSWG页面来监视这一点。

我有与Drupal相同的问题。 考虑到CSS的限制,实现这种工作的方法是在生成菜单HTML时将“活动”类添加到父元素。 在http://drupal.org/node/219804有一个很好的讨论,其结果是这个function已经被引入到nicemenus模块的版本6.x-2.x中。; 由于这仍在开发中,我已经将修补程序反向移植到http://drupal.org/node/465738上的6.x-1.3,以便我可以继续使用模块的生产就绪版本。;

许多人回答jQuery父母,但只是为了增加,我想分享一个快速的代码片段,我用于添加类到我的导航,所以我可以添加样式li的只有子菜单,而不是li那不是。

 $("li ul").parent().addClass('has-sub'); 

我其实碰到了和原来的海报一样的问题。 只有使用.parent() jQueryselect器有一个简单的解决scheme。 我的问题是,我使用.parent而不是.parent() 。 我知道的愚蠢的错误。

绑定事件(在这种情况下,因为我的标签在Modal中,我需要将它们与.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; }) 

这里是HTML ..

 <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> 

当然,你可以重复那个模式

虽然CSS不能ASCEND,但不能抓住另一个元素的父元素。 让我重申:

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

 ul * a { property:value; } 

在这个例子中,ul是某个元素的父元素,该元素是anchor的父元素。 使用这种方法的缺点是,如果有包含锚的任何子元素的ul,它将inheritance指定的样式。

您也可以使用子select器,因为您必须指定父元素。

 ul>li a { property:value; } 

在这个例子中,锚点必须是一个li的后代,必须是ul的子元素,这意味着它必须在ul声明之后的树内。 这将是一个更具体一些,只会抓住一个列表项目,包含一个锚点和是ul的孩子。

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

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

这应该抓住ul类与菜单的类,并且只包含一个活动类的锚的子列表项。

另一个想法刚刚发生在我身上,可能是一个纯粹的CSS解决scheme。 将活动class级显示为一个绝对定位的块,并设置其风格来掩盖家长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的人…

select父母是微不足道的。 您需要某种types的getElementsByClass函数,除非您可以让您的drupal插件为活动项目分配一个ID而不是Class。 我提供的function是我从其他一些天才手中抓起来的。 它工作的很好,只要记住,当你debugging时,函数将总是返回一个节点数组,而不仅仅是一个节点。

 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; }