如何选择里面没有链接的元素?
Posted
技术标签:
【中文标题】如何选择里面没有链接的元素?【英文标题】:how to select element that does NOT have a link inside it? 【发布时间】:2012-01-30 05:29:04 【问题描述】:鉴于此 html:
<ul>
<li><a href="/artists/gil_elvgren/activity_stream">Activity Stream</a></li>
<li><a href="/artists/gil_elvgren/likes">Likes</a></li>
<li>Favorites</li>
<li><a href="/artists/gil_elvgren/follows">Follows</a></li>
<li><a href="/artists/gil_elvgren/sketchbook_comments">Whiteboard</a></li>
</ul>
我想将class="current"
注入到其中没有链接的单个行项目中。
如何使用 jQuery 查找不包含子元素的元素?
【问题讨论】:
【参考方案1】:使用:has
和:not
选择器选择没有<a>
子元素的<li>
元素:
$("li:not(:has(a))").addClass("current");
jsFiddle
-- 编辑--
虽然这可能是最短的解决方案,但不考虑可读性,但就速度而言,它绝对不是最好的解决方案。
考虑到这一点,我建议您查看@bazmegakapa 提供的出色answer。
由于您(或包括我在内的任何其他人)最终可能会多次使用此功能,因此我使用此插件/方法对 jQuery 进行了一些扩展,您可以使用该插件/方法来DRY您的代码:
jQuery.fn.thatHasNo = function(element, method)
if (typeof method === "undefined" || method === null) method = "children";
return this.not(function()
return $(this)[method](element).length;
);
;
你可以打电话给谁:
$("li").thatHasNo("a").addClass("current");
默认情况下(如果未传递方法的第二个参数),此扩展将检查是否有任何直接后代(children)与提供的选择器匹配。但是,您可以提供任何 tree-traversal parameter 作为方法的第二个参数。所以,这可以写成以下任何一种:
$("li").thatHasNo("a", "children").addClass("current");
//...
$("li").thatHasNo("a", "find").addClass("current");
//...
$("li").thatHasNo(".class", "siblings").addClass("lame");
我已更新 jsFiddle 以反映这一点。
【讨论】:
我在回答中添加了一些关于这些选择器(:has()
和 :not
)的注释。
+1 很棒的插件 :)。我可以建议typeof method == 'undefined'
而不是method == null
吗?
您可以添加它,但由于它是一个参数并且根据定义已经定义,因此无需检查未定义 :)
如果调用函数时省略参数,则为undefined
。它适用于您,因为您使用==
,不适用于===
,因为它不是null
。
你是对的,我刚刚意识到同样的事情 :) javascript 有时会很奇怪。最初这是一段咖啡脚本:gist.github.com/1540061【参考方案2】:
您应该使用带有过滤功能的.not()
方法(基本上是否定的.filter()
)。
$('li') /* select the elements you want to test */
.not(function () /* run a filter function on them */
/* those that have a direct children link (use find() if you need
any kind of children) will return true thus excluded */
return $(this).children('a').length;
)
.addClass('current'); /* add our beloved class */
jsFiddle Demo
您也可以使用复杂的选择器,如 @Krule suggested,但我发现它的可读性较差,甚至 jQuery manual on :not() 也警告它:
.not() 方法最终将为您提供更具可读性 选择而不是将复杂的选择器或变量推入 :not() 选择器过滤器。在大多数情况下,这是一个更好的选择。
另外,:has()
也不是很推荐:
因为 :has() 是一个 jQuery 扩展而不是 CSS 的一部分 规范,使用 :has() 的查询不能利用 本机 DOM querySelectorAll() 提供的性能提升 方法。为了在现代浏览器中获得更好的性能,请使用 $("your-pure-css-selector").has(selector/DOMElement) 代替。
【讨论】:
我添加了一个注释指向您的答案,并通过使用thatHasNo
方法扩展 jQuery 对其进行了扩展。【参考方案3】:
$("li").each(function()
if($(this).children().length == 0)
//found current..
$(this).addClass("current");
);
【讨论】:
这只有在li
根本没有子元素时才有效。我的意思是,OP 只想要那些没有 a
孩子的人。【参考方案4】:
我建议您在 <li>
中添加一个 <span>
元素,以区分其中包含链接的元素。
<ul>
<li><a href="/artists/gil_elvgren/activity_stream">Activity Stream</a></li>
<li><a href="/artists/gil_elvgren/likes">Likes</a></li>
<li><span>Favorites</span></li>
<li><a href="/artists/gil_elvgren/follows">Follows</a></li>
<li><a href="/artists/gil_elvgren/sketchbook_comments">Whiteboard</a></li>
</ul>
CSS:
ul li a /* Link CSS */
ul li span /* Current CSS */
【讨论】:
如果他能做到这一点,为什么不在那里添加类? 这个答案没有解决问题。以上是关于如何选择里面没有链接的元素?的主要内容,如果未能解决你的问题,请参考以下文章