出于某种原因,$('#p-foo').siblings('.bar')
有效,但$('#g-foo').siblings('.bar')
没有。任何人都可以向我指出为什么会这样吗?
<div>
<p id="p-foo"></p>
<p class="bar"></p>
</div>
<svg>
<g id="g-foo"></g>
<g class="bar"></g>
</svg>
我写了a quick test script来证明问题:
var selector = '.bar',
attribute = '[class=bar]';
var check = function (foo, d) {
console.log(d + ' matches ' + foo.siblings(d).length);
};
var p_foo = $('#p-foo');
console.log('DIV');
check(p_foo, selector);
check(p_foo, attribute);
var g_foo = $('#g-foo');
console.log('SVG');
check(g_foo, selector);
check(g_foo, attribute);
输出是:
DIV
.bar matches 1
[class=bar] matches 1
SVG
.bar matches 0
[class=bar] matches 1
答案 0 :(得分:3)
我认为这是一个有趣的问题,所以我做了一些源代码研究。
.siblings()
电话
$.filter
,代表Sizzle并最终使用过滤器here。
如果您使用[class=bar]
选择器,Sizzle会使用ATTR
filter,它只检索属性并对其值进行相等性检查。这适用于p
和g
。
如果您使用.bar
选择器,则Sizzle会使用CLASS
filter,{{3}}使用针对elem.className
的正则表达式。但是,在SVG元素中,className
不是字符串,而是SVGAnimatedString
的一个实例(说实话,我从来没有完全包裹我的脑袋,但它似乎有animValue
和baseValue
都是{{1}}和{{1}}。正则表达式失败,元素不匹配。
我相信Sizzle有额外的处理,如果整个文档都可以使这个工作 SVG或XML,但因为这个SVG嵌入在HTML文档中,所以不会启动。