查找没有特定祖先的后代元素
Find descendant elements that do not have a specific ancestor
我希望能够 select 一个元素并找到具有特定 class 但不包含在相似父元素中的所有后代元素。很难描述:
Html:
<div class="js-test js-1">
<div class="b">1</div>
<div class="b">1</div>
<div class="d">
<div class="b">1</div>
</div>
<div class="js-test js-2">
<div class="b">2</div>
<div class="b">2</div>
<div class="b">2</div>
<div class="d">
<div class="b">2</div>
</div>
<div class="js-test js-3">
<div class="b">3</div>
<div class="b">3</div>
<div class="b">3</div>
<div class="b">3</div>
<div class="d">
<div class="b">3</div>
</div>
</div>
</div>
</div>
已尝试 jQuery:
$(document).ready(function(){
function test(element)
{
var test2 = element.find('.b :not(.js-test .b)');
console.log(test2.length);
}
console.clear();
test($('.js-1'));
test($('.js-2'));
test($('.js-3'));
});
预期结果:
3
4
5
实际结果:
0
0
0
您必须进行一些过滤以仅计算 .b
的出现次数,其中最接近的 .js-test
等于 element
:
element.find('.b').filter(function() {
return $(this).closest('.js-test').is(element);
}).length;
Here's a fiddle
尝试
// descendant `.b` of `element`,
// descendant `.b` of `element`, not `.b`, not `.js-test`
var test2 = element.find("> .b, > :not(.b):not(.js-test) .b");
jsfiddle http://jsfiddle.net/ku2pdn2j/4/
$(document).ready(function(){
function test(element) {
var test2 = element.find("> .b, > :not(.b):not(.js-test) .b");
console.log(test2.length, test2);
}
console.clear();
test($('.js-1'));
test($('.js-2'));
test($('.js-3'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div class="js-test js-1">
<div class="b">1</div>
<div class="b">1</div>
<div class="d">
<div class="b">1</div>
</div>
<div class="js-test js-2">
<div class="b">2</div>
<div class="b">2</div>
<div class="b">2</div>
<div class="d">
<div class="b">2</div>
</div>
<div class="js-test js-3">
<div class="b">3</div>
<div class="b">3</div>
<div class="b">3</div>
<div class="b">3</div>
<div class="d">
<div class="b">3</div>
</div>
</div>
</div>
</div>
选择器 .b :not(.js-test .b)
查找 .b
元素的后代,这些元素不是 .js-test .b
元素。这个选择器的问题是双重的:
每个 .b
元素都是 .js-test
元素的后代。这包括直接嵌套在您正在测试的每个上下文 .js-test
元素 中的 .b
元素。
第一个.b
和第一个:not()
之间的space表示后代选择器,也就是:not()
表示的元素很可能 :not(.b)
完全匹配并且仍然匹配。
但是您的 .b
个元素中的 none 个元素有任何元素后代,这就是您所有测试结果为零的真正原因。
由于不能直接创建context元素对应的选择器(参数element
),需要像billyonecan提出的那样写一个自定义的过滤函数,根据是否过滤它最近的 .js-test
祖先是上下文元素。
我最终使用了类似于 的答案:
$(document).ready(function(){
function test(element)
{
var all = element.find('.b');
var exclude = element.find('.js-test .b');
var test = all.not(exclude);
console.log(test.length);
}
console.clear();
test($('.js-1'));
test($('.js-2'));
test($('.js-3'));
});
实际结果:
3
4
5
预期应用程序的结果集非常小,我认为这里的任何解决方案在性能上都没有显着差异。
我希望能够 select 一个元素并找到具有特定 class 但不包含在相似父元素中的所有后代元素。很难描述:
Html:
<div class="js-test js-1">
<div class="b">1</div>
<div class="b">1</div>
<div class="d">
<div class="b">1</div>
</div>
<div class="js-test js-2">
<div class="b">2</div>
<div class="b">2</div>
<div class="b">2</div>
<div class="d">
<div class="b">2</div>
</div>
<div class="js-test js-3">
<div class="b">3</div>
<div class="b">3</div>
<div class="b">3</div>
<div class="b">3</div>
<div class="d">
<div class="b">3</div>
</div>
</div>
</div>
</div>
已尝试 jQuery:
$(document).ready(function(){
function test(element)
{
var test2 = element.find('.b :not(.js-test .b)');
console.log(test2.length);
}
console.clear();
test($('.js-1'));
test($('.js-2'));
test($('.js-3'));
});
预期结果:
3
4
5
实际结果:
0
0
0
您必须进行一些过滤以仅计算 .b
的出现次数,其中最接近的 .js-test
等于 element
:
element.find('.b').filter(function() {
return $(this).closest('.js-test').is(element);
}).length;
Here's a fiddle
尝试
// descendant `.b` of `element`,
// descendant `.b` of `element`, not `.b`, not `.js-test`
var test2 = element.find("> .b, > :not(.b):not(.js-test) .b");
jsfiddle http://jsfiddle.net/ku2pdn2j/4/
$(document).ready(function(){
function test(element) {
var test2 = element.find("> .b, > :not(.b):not(.js-test) .b");
console.log(test2.length, test2);
}
console.clear();
test($('.js-1'));
test($('.js-2'));
test($('.js-3'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div class="js-test js-1">
<div class="b">1</div>
<div class="b">1</div>
<div class="d">
<div class="b">1</div>
</div>
<div class="js-test js-2">
<div class="b">2</div>
<div class="b">2</div>
<div class="b">2</div>
<div class="d">
<div class="b">2</div>
</div>
<div class="js-test js-3">
<div class="b">3</div>
<div class="b">3</div>
<div class="b">3</div>
<div class="b">3</div>
<div class="d">
<div class="b">3</div>
</div>
</div>
</div>
</div>
选择器 .b :not(.js-test .b)
查找 .b
元素的后代,这些元素不是 .js-test .b
元素。这个选择器的问题是双重的:
每个
.b
元素都是.js-test
元素的后代。这包括直接嵌套在您正在测试的每个上下文.js-test
元素 中的.b
元素。第一个
.b
和第一个:not()
之间的space表示后代选择器,也就是:not()
表示的元素很可能:not(.b)
完全匹配并且仍然匹配。但是您的
.b
个元素中的 none 个元素有任何元素后代,这就是您所有测试结果为零的真正原因。
由于不能直接创建context元素对应的选择器(参数element
),需要像billyonecan提出的那样写一个自定义的过滤函数,根据是否过滤它最近的 .js-test
祖先是上下文元素。
我最终使用了类似于
$(document).ready(function(){
function test(element)
{
var all = element.find('.b');
var exclude = element.find('.js-test .b');
var test = all.not(exclude);
console.log(test.length);
}
console.clear();
test($('.js-1'));
test($('.js-2'));
test($('.js-3'));
});
实际结果:
3
4
5
预期应用程序的结果集非常小,我认为这里的任何解决方案在性能上都没有显着差异。