问题
我有一个元素$(elt_Main)
(<span id="a">
)
我在上面调用$(elt_Main).find(selector);
带选择器selector = ':not(span span)';
但是jquery**没有给出我想要的所有子元素。
示例[测试1.html]
- 假设html中的内容是::
<body>
<span id="a">The first <span class="red">signature <span class="green">for the .find() <span class="blue">method accepts</span> a selector</span> <strong>expression</strong> of the <span class="green">same type that we can pass to the</span> $() function</span>. The <span class="red">elements</span> will be filtered by testing whether they match this selector; all parts of the selector <strong>must lie inside of an element</strong> on which .find() is called.</span>
</body>
- 该javascript是::
let elt_Main = document.getElementById('a');
// ...
html_ResultAppend += hr_3;
selector = ':not(span span)'; // <<< watch
jqElt = $(elt_Main).find(selector); // <<< watch
- 提供调试输出的js是::
for (let o of jqElt) {
html_ResultAppend += hr_4;
html_ResultAppend += o.outerHTML;
}
jqElt
的结果将是::
<strong>expression</strong>
<strong>must lie inside of an element</strong>
- 但预期结果应为::
<span class="red">signature <span class="green">for the .find() <span class="blue">method accepts</span> a selector</span> <strong>expression</strong> of the <span class="green">same type that we can pass to the</span> $() function</span>
<span class="red">elements</span>
<strong>expression</strong>
<strong>must lie inside of an element</strong>
- PB &原因是:
- 缺少这2个元素**
<span class="red">signature <span class="green">for the .find() <span class="blue">method accepts</span> a selector</span> <strong>expression</strong> of the <span class="green">same type that we can pass to the</span> $() function</span>
<span class="red">elements</span>
- (我认为)jquery的逻辑是(这是错误的)::
<span id="a"> <span class="red">signature ...
- 〉
<span class="red">signature ...
位于跨度<span id="a">
内 - 〉我们说
:not(span span)
- 〉因此不应选择此选项
(^与上述<span id="a"> <span class="red">elements</span>
相同)
- 我的逻辑是:
<span id="a">
($(elt_Main)
)是调用.find()
的元素
- 当我们在
.find()
中使用css选择器时,<span id="a">
($(elt_Main)
)本身不应 * 被考虑/播放任何效果**
- 当我们在
- 否则,在下面的例子中就没有任何意义了:
比如说我们这样做$(elt_Main).find('span');
这应该只找到elt_Main
的子元素,它是span
--这是正确的。
如果我们在使用use selector时考虑到<span id="a">
($(elt_Main)
),那么这将选择<span id="a">
($(elt_Main)
)本身--这是错误的。
- 换句话说
当.find()
被<span id="a">
($(elt_Main)
)调用时,
选择器应该将其(要搜索的元素<span id="a">
($(elt_Main)
))视为标签<span id="a">
不存在(--它不应该播放任何效果),并且只在innerHtml
上搜索。
证明我的逻辑--示例[test1.html test2.html]
JS选择元素并写入HTML主体。
- 测试1使用
.find()
+:not()
**
- 测试1使用
- 测试2仅使用
:not()
**
- 测试2仅使用
测试2删除了$(elt_Main)
中的<span id="a">
标签
- (--正如我上面所说的--我们应该把它当作标签
<span id="a">
不存在一样) - (如果你认为我错了,你说:不要删除
<span id="a">
,使test1和test2产生相同的结果-〉检查test1和test3--它甚至更糟) - 我们清楚地看到
test1
输出缺少元素test2
输出正确
(回到问题)
与:not
选择器一起使用的jquery .find()
缺少某些元素(选择器受.find()
调用元素影响,但不应受影响)
那么,是jQuery错了吗?还是我错了?为什么?
2条答案
按热度按时间yeotifhr1#
好吧,我有一个猜测,所以我只是要张贴它作为一个答案。
正如我在评论中所写的,
$(selector).find(selector)
基本上像一个两遍过滤器一样工作,它不应该提出任何沙盒式的机制来阻止第二遍选择“检测”候选对象的任何事实/属性,包括但不限于它们的父对象。然而,我对
$(A).find(A B)
的怀疑是,它在幕后并不像这样工作:1.选择A的所有后代
1.从步骤1返回的选择中选择
B
并且父节点为A
的节点(类似于foreach c in S: if c is B and c.parent is A: nS.add(c)
)相反,它可能在幕后这样工作:
1.选择A的所有后代
1.从步骤1返回的选择中选择所有A
1.从步骤2返回的选择中选择所有B
如果步骤2没有返回任何元素,那么步骤3也不会返回任何元素。
下面是一个显示“等价物”的示例:
我不认为当前实现后代选择器的方式是正确的,我确实想知道jQuery开发人员会如何讨论它(但这实际上只是我的猜测,我还没有检查任何源代码来确保它是100%正确的)。
nfeuvbwi2#
您的选择器要求任何不是其他
<span>
的<span>
后代的元素。后代测试不仅适用于DOM中起点下的子树(.find()
的根元素);它涉及到整个DOM。它必须以这种方式工作。你声称"它不应该"是对选择器工作方式的误解。因为您的起始元素本身就是
<span>
,所以子树中的 * 所有 *<span>
元素都是<span>
的后代,所以它们都不匹配选择器。您可以尝试使用原生
.querySelectorAll()
进行测试:看看你能得到什么。
下面是一个更清楚的示例,使用了一个包含起始点父元素的
:not()
选择器:x一个一个一个一个x一个一个二个x
从外部跨度开始,该选择器(
:not(.foo span)
)要求不是<span>
且从类"foo"的元素派生的任何元素。起点 * do * 下的所有<span>
标记都与:not
中的该选择器匹配,因为它们都从父<div>
派生。因此,该查询仅找到一个元素,即<b>
。一般来说,在一个已经使用了近20年的平台上发现一个严重的错误是相当不可能的,不是不可能,而是不太可能。