jquery AMD 插件 - each() 不循环

jquery AMD plugin - each() does not loop?

本文关键字:循环 each AMD 插件 jquery      更新时间:2023-09-26

我试图在AMD模式中制作一个jquery插件,但似乎我无法让each()循环。它只返回第一项,但我有三项。

索引.html,

<body>
    <div class="element">
        1
    </div>
    <div class="element">
        2
    </div>
    <div class="element">
        3
    </div>
</body>

在 HTML head 中,

$(document).ready(function(){
    $(".element").plugin2().data('plugin_plugin2').someMethod();
});

插件.js,

!function(root, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['jquery'], factory);
    } else {
        factory(root.jQuery);
    }
}(this, function($) {
    var pluginName = 'plugin2',
        defaults = {
            param1:       'param1',
            param2:       'param2'
        };
    var Plugin = function(element, options) {
        this.element    = element;
        this.options    = options;
    };
    Plugin.prototype = {
        constructor: Plugin,
        someMethod: function(options) {
            var rootScope = this;
            return rootScope.element.each(function(e){
                console.log(e); // you get 0 only
                console.log(this); // the first <div class="element"> only
            });
        }
    };
    $.fn[pluginName] = function(options) {
        options = $.extend(true, {}, defaults, options);
        return this.each(function() {
            var $this = $(this);
            $this.data('plugin_' + pluginName, new Plugin($this, options));
        });
    };
    $.fn[pluginName].defaults = defaults;
    $.fn[pluginName].Plugin   = Plugin;
});

任何想法我做错了什么?

像所有jQuery的getter/setter方法一样,data是不对称的:设置时,它设置jQuery集中的所有元素,但是当获取时,它只从第一个元素获取

所以这行:

$(".element").plugin2().data('plugin_plugin2').someMethod();

。只会给你集合中第一个元素的数据。如果你想查看所有三个的数据,你也需要在那里循环:

$(".element").plugin2().each(function() {
    $(this).data('plugin_plugin2').someMethod();
});

但从根本上说,你的代码所做的不是你在插件中实现方法的方式(尤其是出于这个原因)。相反,在插件中实现方法的常用方法是让主插件方法接受一个字符串(方法名称),例如:

$(".element").plugin2().plugin2("someMethod");

谢谢。 那么它如何寻找这样做的样板 - $(".element").plugin2().plugin2("someMethod");

下面是一个非常小的例子:

(function($) {
  var methods = {
    init: function() {
      // If you have to do different things on different
      // elements, use this.each(...) or similar
      this.css("color", "red");
      return this;
    },
    color: function(color) {
      // If you have to do different things on different
      // elements, use this.each(...) or similar
      this.css("color", color);
      return this;
    },
    increment: function(color) {
      // For example, this is effectively a `this.each(...)`:
      this.text(function() {
        return +$(this).text() + 1;
      });
      return this;
    }
  };
  var slice = Array.prototype.slice;
  $.fn.foo = function(method) {
    var f = methods[method || "init"];
    if (!f) {
      throw "Unknown method for plugin `foo`: '" + method + "'";
    }
    return f.apply(this, slice.call(arguments, 1));
  };
})(jQuery);
setTimeout(function() {
  $(".element").foo();
}, 500);
setTimeout(function() {
  $(".element").foo("color", "green");
}, 1000);
setTimeout(function() {
  $(".element").foo("increment");
}, 1500);
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>