是否有一种方法可以根据类中的子元素的类来选择父元素?这个例子是与我有关的HTML输出的一个很好的菜单插件http://drupal.org。输出是这样呈现的:
<ul class="menu">
<li>
<a class="active">Active Page</a>
</li>
<li>
<a>Some Other Page</a>
</li>
</ul>
我的问题是,是否可以将样式应用到包含活动类的锚的列表项。显然,我更希望将列表项标记为活动,但我无法控制生成的代码。我可以使用javascript (JQuery弹簧想到)执行这类事情,但我想知道是否有一种方法来做到这一点使用CSS选择器。
为了明确起见,我想对列表项应用样式,而不是锚。
根据维基百科:
选择者无法提升
CSS不提供选择满足特定条件的元素的父元素或祖先元素的方法。更高级的选择器方案(比如XPath)将支持更复杂的样式表。然而,CSS工作组拒绝父选择器建议的主要原因与浏览器性能和增量呈现问题有关。
对于将来搜索SO的人来说,这也可能被称为祖先选择器。
更新:
Selectors Level 4 Spec允许您选择选择的哪个部分是主题:
The subject of the selector can be explicitly identified by prepending
a dollar sign ($) to one of the compound selectors in a selector.
Although the element structure that the selector represents is the
same with or without the dollar sign, indicating the subject in this
way can change which compound selector represents the subject in that
structure.
Example 1:
For example, the following selector represents a list item LI unique child of
an ordered list OL:
OL > LI:only-child
However the following one represents an ordered list OL having a unique child,
that child being a LI:
$OL > LI:only-child
The structures represented by these two selectors are the same,
but the subjects of the selectors are not.
尽管这在任何浏览器中都不可用(目前是2011年11月),也不能作为jQuery的选择器。
实际上我遇到了和原来海报上一样的问题。有一个简单的解决方案,只需使用.parent() jQuery选择器。我的问题是,我使用的是.parent而不是.parent()。我知道这是个愚蠢的错误。
绑定事件(在这种情况下,因为我的选项卡是在模式,我需要绑定他们与。live而不是一个基本的。点击。
$('#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>
当然你可以重复这个模式,用更多的LI
我刚刚想到的另一个想法可能是一个纯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;
}
对于那些想使用javascript而不使用jquery的人…
选择父对象很简单。您需要某种类型的getElementsByClass函数,除非您可以让drupal插件为活动项分配一个ID而不是Class。我提供的函数是我从SO上的其他天才那里抢来的。它工作得很好,只是在调试时要记住,该函数总是返回一个节点数组,而不仅仅是单个节点。
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;
}
未来答案与CSS4选择器
新的CSS规范包含一个实验性的:有伪选择器,可能能够做这件事。
li:has(a:active) {
/* ... */
}
目前浏览器对这方面的支持基本不存在,但官方规范正在考虑。
2012年的答案在2012年是错误的,在2018年更是错误的
虽然CSS确实不能ASCEND,但不能抓取另一个元素的父元素是不正确的。让我重申:
使用HTML示例代码,可以在不指定li的情况下获取li
ul * a {
property:value;
}
在这个例子中,ul是某个元素的父元素,而该元素是anchor的父元素。使用此方法的缺点是,如果ul的任何子元素包含一个锚,它将继承指定的样式。
你也可以使用子选择器,因为你必须指定父元素。
ul>li a {
property:value;
}
在这个例子中,锚必须是li的后代,li必须是ul的子结点,这意味着它必须在ul声明之后的树中。这将更具体一点,它只抓取包含锚点并且是ul的子元素的列表项。
所以,用代码来回答你的问题。
ul.menu > li a.active {
property:value;
}
这将抓取带有menu类的ul,以及只包含带有active类的锚的子列表项。