想要使用一些"可读"的方法从元素中获取文本节点,我发现了这种我无法解释的奇怪行为.
使用以下HTML标记:
<div>text node <b>and b element</b></div>
Run Code Online (Sandbox Code Playgroud)
文本节点不是DOM元素,所以我想知道这是否有效:
var textnode = $('div').contents().filter(':not(*)'); //returns jq empty set
Run Code Online (Sandbox Code Playgroud)
即使使用.filter('*')和不返回文本节点但其他元素(b)也会失败.
所以测试它,我使用not()方法,我不确定它是否适用于文本节点:
var textnode = $('div').contents().not('*'); //returns jq empty set
Run Code Online (Sandbox Code Playgroud)
我们承认吧.但是这个返回文本节点:
var textnode = $('div').contents().not(':not(:not(*))'); //returns text node in set
Run Code Online (Sandbox Code Playgroud)
那么为什么 .not('*')失败的时候.not(':not(:not(*))')有效呢?
我无法解释.
PS: .filter(':not(:not(:not(*)))')失败,而我期待它完全像.not(':not(:not(*))')
因为.not(':not(:not(*))')不是一个简单的选择器(基本上,它有多个“部分”),所以对其进行区别对待。
简单的选择器(如.filter(':not(*)')和)通过名为 的布尔指示符.not('*')传递给函数。该指示符将附加内容包裹在 的选择器周围。jQuery.filter()not:not(...).not(selector)
jQuery.filter()返回通过选择器过滤的节点。它有一个额外的检查,因此它只返回nodeType 1(元素)的节点。
对于复杂的选择器(例如.not(':not(:not(*))')),该机制的工作方式有点不同;选择器被传递,jQuery.filter()但not布尔指示符未设置。相反,返回的节点jQuery.filter()将与原始节点列表进行比较,并根据您是否使用.not()或进行筛选或筛选.filter()。由于jQuery.filter()仅返回元素,因此在与原始节点列表进行比较时,它找不到文本元素的任何匹配项。对于您的.not(':not(:not(*))'),这意味着根据此逻辑,不应过滤掉文本节点,因为它不在 所返回的要过滤的节点列表中jQuery.filter()。
这些不同机制的原因可能是您不能简单地包装:not(...)任何复杂的选择器;它可能会改变预期的含义。
.contents()尽管他们在文档中确实声明文本节点不受大多数 jQuery 其余部分的支持。可以通过仅从winnow函数中显式返回 nodeType 1 节点来解决此问题。
原始 jQuery 1.11.3 代码:
function winnow( elements, qualifier, not ) {
//...
return jQuery.grep( elements, function( elem ) {
return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
});
}
Run Code Online (Sandbox Code Playgroud)
更改后的代码:
function winnow( elements, qualifier, not ) {
//...
return jQuery.grep( elements, function( elem ) {
return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not && elem.nodeType === 1;
});
}
Run Code Online (Sandbox Code Playgroud)
我不知道这是否属于错误,但它至少是 jQuery 中可解决的不一致问题。您可能想将其报告给 jQuery。
| 归档时间: |
|
| 查看次数: |
153 次 |
| 最近记录: |