6

http://jsfiddle.net/garnwraly/sfrwU/2/

仅给定 HTML

<li>
    <button id="bam">click</button>
</li>

和这个脚本

$('body').on('click', 'button', function (e) {
    //console.log( e.currentTarget == $('button')[0] ); //true;
    //console.log($('li').is('li:first')); //true

    console.log($(e.currentTarget).parent().is('li:first')) //false
    console.log($('button').parent().is('li:first')); //true
    console.log($($('button')[0]).parent().is('li:first')); //false
});

为什么是$(e.currentTarget).parent().is('li:first')假的?

4

2 回答 2

4

在运行时通过 jQuery 代码进行逐步调试后,结果证明这是方法在jQuery()方法中使用的方式的问题is()。众所周知,您可以将上下文传递给方法,并且在内部,此上下文与is()方法一起使用(并且为各种选择器设置不同的设置)。

使用$(e.currentTarget)时,上下文设置为触发事件的按钮。当$('button')使用时,上下文被设置为Document对象。当您考虑需要如何限定这些选择器时,这是有道理的。

这是该is()方法的相关部分:

jQuery( selector, this.context ).index( this[0] ) >= 0

基于此,当作为 $(e.currentTarget) 运行时,对该jQuery()方法的调用将评估为:

jQuery("li:first", "button#bam").index( this[0] ) >= 0

这显然是返回-1,并报告为false

于 2013-04-20T02:17:37.620 回答
3

我认为它可能:first只关心匹配- 如果 jQuery 对象是从 DOM 元素构造的,则不会进行选择器匹配。注意

console.log($(document.getElementById('bam')).is(':first'));

也记录false

我不认为这种行为是正确的,并且可能应该记录一个错误,但即使它工作正常,我也不认为在这种情况下测试:first真的有任何好处。如果您使用.parent()从单个元素开始向上导航 DOM 到父节点,那么询问父节点是否是第一个元素是没有意义的 - 总会有一个父节点(当然除了 DOM 根),并且总是只有一个。

如果你用 来做这件事:first-child,这实际上会很有趣但不一定相关,那么它会像人们预期的那样工作,因为:first-child它实际上是关于 DOM 的结构。:first限定符只是第一个匹配的元素。

于 2013-04-20T00:48:50.107 回答