jQuery:是否可以将字段/方法附加到jQuery包装器对象?

时间:2009-02-25 22:20:36

标签: javascript jquery plugins

我正在尝试编写一个插件,它将为jQuery包装器对象添加一些方法。基本上,我想像这样初始化它:

var smart = $('img:first').smartImage();

'smartImage'插件会将2个方法附加到'smart'引用的对象上,因此我将能够执行以下操作:

smart.saveState();
// do work
smart.loadState();

不幸的是,我无法弄清楚如何将这两种方法附加到包装器对象。我的代码遵循典型的jQuery插件模式:

(function($)
{
    $.fn.smartImage = function()
    {
        return this.each(function()
        {
            $(this).saveState = function() { /* save */ }
            $(this).loadState = function() { /* load */ }
        }
    }
 }

在我调用smartImage()之后,既没有定义'saveState'也没有定义'loadState'。我做错了什么?

3 个答案:

答案 0 :(得分:5)

您实际上是在smartImage()函数中返回一个jQuery对象。这是编写jQuery插件的正确方法,因此您可以将其与其他jQuery函数链接起来。

我不确定是否有办法做你想做的事。我建议如下:

(function($) {
     var smartImageSave = function() { return this.each(function() { } ); };
     var smartImageLoad = function() { return this.each(function() { } ); };

     $.fn.extend( { "smartImageSave":smartImageSave, 
                     "smartImageLoad":smartImageLoad });
 });

 var $smart = $("img:first");
 $smart.smartImageSave();
 $smart.smartImageLoad();

这是我熟悉并成功使用的一种技术。

答案 1 :(得分:5)

您不能以您演示的方式附加方法/属性,因为正如您所说,jQuery对象只是它包含的任何DOM元素的包装。你当然可以附加方法/属性,但是当jQuery再次选择它们时它们将不会持久存在。

var a = $('.my-object');
a.do_something = function(){ alert('hiya'); }
a.do_something(); // This alerts.

var b = $('.my-object');
b.do_something(); // Freak-out.

如果希望jQuery对象在第二次恢复时存在方法,则需要将其分配给jQuery.fn。所以你可以定义你的辅助方法,将它分配给jQuery.fn,并使用jQuery数据设置为你维护状态......

$.fn.setup_something = function()
{
    this.data('my-plugin-setup-check', true);
    return this;
}

$.fn.do_something = function()
{
    if (this.data('my-plugin-setup-check'))
    {
        alert('Tada!');
    }
    return this;
}

var a = $('.my-object').setup_something();
a.do_something(); // Alerts.
$('.my-object').do_something(); // Also alerts.

我建议您查看http://docs.jquery.com/Internals/jQuery.datahttp://docs.jquery.com/Core/data#name

答案 2 :(得分:2)

我不完全确定你为什么以这种方式设计你的插件 - 你可能想要考虑一下jonstjohn的建议 - 但是以下应该与你要求的类似:

jQuery.fn.extend({
    smartImage: function() {
        return {
            saveState: function() { /* save */ },
            loadState: function() { /* load */ }
        };
    }
});