如何选择里面没有链接的元素?

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 选择器选择没有&lt;a&gt; 子元素的&lt;li&gt; 元素:

$("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】:

我建议您在 &lt;li&gt; 中添加一个 &lt;span&gt; 元素,以区分其中包含链接的元素。

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

【讨论】:

如果他能做到这一点,为什么不在那里添加类? 这个答案没有解决问题。

以上是关于如何选择里面没有链接的元素?的主要内容,如果未能解决你的问题,请参考以下文章

如何将一个选择元素与另一个选择语句相关联

如何选择没有特定祖先元素的元素

如何使用jQuery选择没有特定类名的元素?

如果没有元素如何选择

如何在没有事件的情况下选择DOM外部的元素?

css 如何使用JQuery选择没有特定子元素的元素