如何将函数添加到某些jQuery对象,而不是其他jQuery对象?

Dan*_* T. 15 javascript jquery

假设我有一个<ul>清单:

<ul class="products">
    ...
</ul>
Run Code Online (Sandbox Code Playgroud)

我想用jQuery选择它,然后为该对象添加一些函数.例如,我想添加一个addProduct(productData)函数和一个deleteProduct(productId)函数.但是,我希望只将函数添加到选择器返回的对象中.例如,像这样:

var productList = $.extend($('ul.products'), {
    addProduct: function(productData) {
        // add a new li item
    },
    deleteProduct: function(productId) {
        // delete li with id
    }
});
Run Code Online (Sandbox Code Playgroud)

我如何使用jQuery做到这一点?这里的关键点是我只想将函数添加到jQuery选择器返回的实例中.换句话说,我不想修改jQuery的原型或创建插件,因为这些将使所有函数都可用,而我只想将函数添加到一个特定的实例.

Mat*_*att 12

如果你只想在那个单独的 jQuery对象上使用addProductdeleteProduct方法,那么你得到的就可以正常工作了; 但你必须保持对该jQuery对象的引用/仅使用它一次,以保持和方法的存在.addProductdeleteProduct

但是,这些addProductdeleteProduct方法对于特定的jQuery对象是唯一的; 您创建的任何其他jQuery对象上都不存在这些方法;

var productList = $.extend($('ul.products'), {
    addProduct: function(productData) {
        // add a new li item
    },
    deleteProduct: function(productId) {
        // delete li with id
    }
});

// Using this particular jQuery object (productList) will work fine.
productList.addProduct();
productList.removeProduct();

// However, addProduct() does not exist on new jQuery objects, even if they use
// the same selector.
$('ul.products').addProduct(); // error; [object Object] has no method 'addProduct'
Run Code Online (Sandbox Code Playgroud)

对此最好的方法是回归基础并定义接受jQuery对象的单独addProductdeleteProduct函数.如果你想限制这些功能,他们只能在ul.products选择器上工作,你可以这样做;

function addProduct(obj) {
    obj = obj.filter('ul.products');

    // do something with `obj` (its a jQuery object)
}
Run Code Online (Sandbox Code Playgroud)

建议采用这种方法,因为它保持jQuery.fnAPI一致; 否则你会被添加addProduct,并removeProduct一些 jQuery.fn实例,但不是别人,或者让别人他们的使用是多余的.然而addProduct,这种方法removeProduct总是在那里,但如果他们不想使用它们,就不要以任何方式进入.


历史笔记

这个答案最初写于2011年11月,当时jQuery 1.7发布了.从那时起,API发生了很大变化.上面的答案与当前的 2.0.0版本的jQuery有关.

在1.9之前,使用了一个名为jQuery.subused 的小方法,它你想要做的事情有关(但除非你改变你的方法,否则不会帮助你).这会创建一个新的jQuery构造函数,所以你可以这样做;

var newjQuery = jQuery.sub();
newjQuery.fn.addProduct = function () {
    // blah blah
};
newjQuery.fn.deleteProduct = function () {
    // blah blah
};

var foo = newjQuery('ul.products');
foo.deleteProduct();
foo.addProduct();

var bar = jQuery('ul.products');
bar.deleteProduct(); // error
bar.addProduct(); // error
Run Code Online (Sandbox Code Playgroud)

但要小心,$方法别名将引用旧jQuery对象,而不是newjQuery实例.

jQuery.sub在1.9中从jQuery中删除.它现在可以作为插件使用.


Bas*_*ter 6

您可以创建自己的 jQuery 方法,如下所示:

$.fn.addProduct = function(){
  var myObject = $(this);
  // do something
}

// Call it like:
$("ul.products").addProduct();
Run Code Online (Sandbox Code Playgroud)

不过这有点棘手,因为您正在制作非常特定于列表的方法。因此,为了确保您至少应该对对象的类型进行一些检查并正确处理代码(如果当前对象是),假设是一个输入元素。

另一种方法是创建一个接收列表作为参数的普通 Javascript 方法。这样你就可以制定一个更具体的方法。