为什么jQuery add()方法似乎不返回jQuery对象?

时间:2012-07-11 11:47:38

标签: javascript jquery

考虑您要为网页上的许多链接添加ajax功能。

<a href='http://domain/purchase/car' class='purchase'>Car</a>
<a href='http://domain/purchase/bag' class='purchase'>Bag</a>
<a href='http://domain/purchase/laptop' class='purchase'>Laptop</a>

<a href='http://domain/sell/car' class='sell'>Car</a>
<a href='http://domain/sell/bag' class='sell'>Bag</a>
<a href='http://domain/sell/laptop' class='sell'>Laptop</a>

现在,您可以定义一些变量来引用JavaScript代码中的这些链接组:

var purchaseLinks = $('.purchase'),
    sellLinks= $('.sell');

嗯,足够的故事;)。

您可以在this小提琴和this一个中查看问题。

根据jQuery's add() documentation,返回值是新的jQuery对象。再一次,AMAIK在附加到jQuery对象事件的函数处理程序中,this引用DOM元素。

为什么使用add()方法,处理函数的this引用document?我不明白。我无法通过我的知识来形成合乎逻辑的感知。换句话说:

jQueryObject1.click(function(){
    // Here, $(this) is the jQuery object
});

jQueryObject2.click(function(){
    // Here again, $(this) is the jQuery object
});

jQueryObject1.add(jQueryObject2).click(function(){
    // Here $(this) refers to the Document, why?
    // I think jQueryObject1.add(jQueryObject2) should equal jQueryObject3
});

更新:

感谢您的回答。我再次将读者引荐到Live is Deprecated页面,以便每个人都可以改进。

2 个答案:

答案 0 :(得分:4)

你小提琴中的问题是使用.live()。 jQuery文档声明:

  

不支持链接方法。例如,$("a").find(".offsite, .external").live( ... );无效,无法按预期工作。

对于每个人来说,幸运的是.live() method is deprecated,所以你不必再担心这样的事了。您可以使用on代替并利用事件委派。


更新(在@Esailija评论之后)

这就是实际发生的事情。你在这里调用jQuery:

var purchaseLinks = $('.purchase');

这会产生一个jQuery对象,它具有selector属性。然后,您拨打.add(),然后调用内部pushStack方法:

return this.pushStack(isDisconnected(set[0]) || isDisconnected(all[0]) ? all : jQuery.unique(all));

pushStack method创建新的jQuery对象。只用一个参数调用它。以下是该方法的相关部分(请注意nameselector在我们的案例中均为undefined

function (elems, name, selector) {
    // ...

    ret.context = this.context;

    if (name === "find") {
        ret.selector = this.selector + (this.selector ? " " : "") + selector;
    } else if (name) {
        ret.selector = this.selector + "." + name + "(" + selector + ")";
    }

    // Return the newly-formed element set
    return ret;
}

另请注意,this.context现在是文档(因为您的原始jQuery对象未指定上下文,因此假定了最高可能的上下文。)

因此,新形成的元素集没有selector属性,并将文档作为其上下文。当我们调用.live()时,jQuery只需调用.on(),如下所示:

jQuery( this.context ).on( types, this.selector, data, fn );

我们可以看到问题所在。上下文是文档,没有选择器,因此事件处理程序绑定到文档。我们案例中的上述内容实际上是这样的:

jQuery( document ).on( "click", function() {
    //Your event handler
});

您可以通过单击文档中的任意位置(而不仅仅是链接)来触发alert,这样您就可以看到这一点。

故事的寓意?停止使用.live()

答案 1 :(得分:0)

var purchaseLinks = $('.purchase'),
    sellLinks= $('.sell');
purchaseLinks.add(sellLinks).on('click', function(e) {
    e.preventDefault();
    alert(this.href);
});

.add().live()更改为.on()没有错。

http://jsfiddle.net/iambriansreed/q573N/5/