Javascript jQuery插件创作-为不同的元素设置不同的选项

Javascript jQuery插件创作-为不同的元素设置不同的选项,javascript,jquery,jquery-plugins,Javascript,Jquery,Jquery Plugins,我已经创建了一个jQuery插件,除了能够在不同的对象上调用该插件,并且每个对象都保留它所提供的选项之外,它工作得非常好。问题是,如果我在一个对象上调用插件,请说: $('#myDiv1').myPlugin({ option1: 'some text', option2: true, option3: 'another option value' }); $('#myDiv2').myPlugin({ option1: 'different text',

我已经创建了一个jQuery插件,除了能够在不同的对象上调用该插件,并且每个对象都保留它所提供的选项之外,它工作得非常好。问题是,如果我在一个对象上调用插件,请说:

$('#myDiv1').myPlugin({
    option1: 'some text',
    option2: true,
    option3: 'another option value'
});
$('#myDiv2').myPlugin({
    option1: 'different text',
    option2: false,
    option3: 'value for myDiv2'
});
然后在另一个对象上再次调用插件,例如:

$('#myDiv1').myPlugin({
    option1: 'some text',
    option2: true,
    option3: 'another option value'
});
$('#myDiv2').myPlugin({
    option1: 'different text',
    option2: false,
    option3: 'value for myDiv2'
});
然后,如果我回去尝试使用#myDiv1做一些需要保持其原始选项不变的事情,即:

$('#myDiv1').myPlugin.update();
它没有原始选项,但它们将被#myDiv2的选项覆盖。这样做的正确方法是什么,以使每个对象保留给定给它的原始选项?(下面是我在插件中所做的一些示例代码)

我意识到这是某种范围内的蔓延。那么,我如何让我的选项保持连接并保持在它们被赋予的原始对象(即#myDiv1)的范围内呢


编辑:在做一些研究时,我发现可以使用jQuery的.data函数将数据存储到对象中,文档说jQuery UI广泛使用它。正确的做法是使用.data将选项存储在对象上,然后在以后引用时使用.data中存储的选项吗?

您的选项是插件范围的。将它们移动到each()中。
(你为什么要问这个问题?你几乎是自己详细说明了解决方案。)

我也遇到了同样的问题,但只有传递的函数被覆盖。直接的属性持续存在

无论如何,为了进一步解释~reinierpost的含义,将代码更改为此应该是可行的。您必须到处传递“opts”,但我认为这对于将选项从插件范围的名称空间中去掉是必要的

$.fn.myPlugin = function(options) {

    // iterate all matched elements
    return this.each(function() {
        // build main options before element iteration
        var opts = $.extend({}, $.fn.myPlugin.defaults, options);
        callPluginFunctions( this, opts );
    });
};
编辑:这是我的插件的代码

this.each(function() {
    var thisConfig = config;
    thisConfig = $.extend(thisConfig,settings);
    $.attach($(this),thisConfig);
});

...

$.attach = function($target,config){

因此,我没有插件范围的“config”-只是在每个函数中。

首先,您通常希望在扩展方法中处理该命令。其次,您应该将配置附加到每个项目

(function($){
var defaultOptions = { /* default settings here */ };

//called on the native object directly, wrap with $(obj) if needed.
function initializeObject(obj, options) {
  //assign the options to the object instance.
  $(obj).data('myPlugin-options', $.extend(defaultOptions, options) );
  //do other initialization tasks on the individual item here...
}

function updateObject(obj) {
  // use $(obj).data('myPlugin-options');
}

function setOption(obj, key, value) {
  var d = $(obj).data('myPlugin-options');
  d[key] = value;
  $(obj).data('myPlugin-options', d);
}

$.fn.myPlugin = function(command, option, val) {
  if (typeof command == "object") {
    //initialization
    return this.each(function(){
      initializeObject(this, command);
    });
  }
  if (typeof command == "string") {
    // method or argument query
    switch (command.toLowerCase()) {
      case 'option':
        //get value, return the first item's value
        if (typeof val == undefined) return this.eq(0).data('myPlugin-options')[option];
        //set option value
        return this.each(function() {
          setOption(this, option, val);
        });

      case 'update':
        return this.each(function() {
          updateObject(this);
        });
      //other commands here.
    }
  }
}
})(jQuery)
在上面的示例中,您有一个用于jQuery扩展的通用模板,使用以下约定通常是一种很好的形式

Initialization:
  $(...).myPlugin({ initialization-options-here });
Command:
   $(...).myPlugin('command-name'); //where command can be update, etc.
Get Option:
  var myValue = $(...).myPlugin('option', 'option-name');
Set Option:
  $(...).myPlugin('option', 'option-name', newValue);

更新为使用每个对象的数据。

我之所以这样问,是因为我显然不知道解决方案。我已经将this.each函数之前的所有内容移动到this.each(function()中我仍然得到相同的结果。你能澄清一下你的意思吗?现在我真的很困惑。我的意思是,你希望每个匹配元素的_选项1等是分开的,所以你应该复制它们,例如,像Pickle所做的那样。你还没有向我们展示你以后如何访问这些选项,可能还有进一步的问题。是的,这这是我的全部问题…稍后访问选项。我没有将配置附加到对象本身。我在each()中添加了$(this).data('opts',opts;)循环,现在一切都像一个符咒。无论如何,谢谢。嘿,我在reinierpost的帖子后尝试过,但我仍然有相同的问题。问题不是我不能用不同的选项调用不同的对象,而是在我“初始化”一个对象上的插件之后,然后在我返回时用不同的选项初始化一个不同的对象并在第一项上调用任何插件函数,它使用第二项的设置,而不是第一项。我希望这很清楚,如果不清楚,请告诉我。我已更新了我的初始条目,以显示我如何在插件中使用此技术。也许你指的是插件范围的配置对象,而不是在t中初始化的对象他的.each()循环?是的,它将选项附加到我缺少的对象。我看到您使用了$.attached,我最终使用了$.data($(this.data($opts',opts);)。这两者之间有什么真正的区别吗?谢谢$。attach是我在插件中编写的自定义函数-它不像$那样是jQuery核心的一部分。data是&一点都不类似。对于编辑和reinerpost的正确答案,是的,data对象是一个很好的选择。但是,请使用jQuery UI工厂()进行检查.我用它来创建的幻灯片代码(参见:jquery.slideshow.js)太棒了,谢谢。我错过了“将配置附加到每个对象”部分。我最终使用$.data来附加配置,而不是您的建议。这两种方法有什么优点/缺点吗?我想它们可能差不多。另外,我非常喜欢您的插件设置,与jQuery UI非常相似。我也采用了=)谢谢我不会对每个对象都使用.data,因为插件可能会使用事件委托。另外,如果插件在没有任何参数的情况下被调用,那会怎么样?在您的示例中,不会发生任何事情。@vsync它主要是一个指导原则。。。可以检查未定义的对象以及初始化为默认值的对象。我还认为数据应用程序应该应用于每个项目,因为每个项目可以在以后进行调整,以具有不同的选项。我知道这并不完美。。。我只是想指出UI和其他jQuery扩展中似乎使用的一般模式。今天我想到了一些事情:最好保存对每个选择器的引用,对于该选择器,存储适当的选项,而不是每个项本身。假设我有一个插件操作1000个输入字段。如果我想要一个简单的焦点事件来触发一些东西,那么处理所有这些字段并不是明智的内存管理。。只是一个想法每个节点的数据不应该只是指向内存中相同对象的指针吗?