jQuery/Sizzle元素选择器上下文的一个陷阱的分析与解决

现有这样一段HTML:

<div id="div1">
    <span class="a">a1</span>
    <span class="b">b1</span>
    <span class="c">c1</span>
    <div id="div2">
        <span class="a">a2</span>
        <span class="b">b2</span>
        <span class="c">c2</span>
    </div>
</div>

现在用js去查找元素

jQuery

$('div .a, div .b, div .c',$('#div1'))

Sizzle

Sizzle('div .a, div .b, div .c',Sizzle('#div1'))

根据你的想象,上述js代码将返回哪些元素呢?

你可能想,要么就是所有的span,要么就是后面3个span,但其实是返回除了第一个span之外的所有span!

jQuery 1.4.3 到当前最新的 1.7.2 都存在该问题,但1.4.2没有该BUG.

分析了一下jQuery/Sizzle的源码,就明白了。

jquery-1.7.2.js 第5163行, 或者sizzle.js第1221行:

return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );

针对上面的例子,等价于

document.getElementById('div1').querySelectorAll("[id='div1'] div .a, div .b, div .c")
第一段是[id='div1'] div .a, 第二段是div .b, 第三段是div .c 所以导致第一个span被排除,第2第3个却未被排除。

弄清了原因,修正就很简单了,在query表达式每个逗号后面都加上[id=xxx] 的限定就行了。

好在是开源的,我已经在github向jquery/sizzle提交了pull request。

我把这句改成了如下:

return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query.replace(/\,/g,",[id='" + nid + "'] ") ), extra );
测试通过。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值