如何编写面向对象的 jQuery 插件?

how to write object-oriented jQuery plugins?

所以我有一些编写普通插件来做任何事情的经验,但我想转向一个基于对象的事件驱动系统,它可以为最终用户提供更多的动态和可定制性。为了我的问题,我编写了一个小插件,可以简单地突出显示 $(selector).hover() 事件中的文本。

这里是 JS/jQuery:

(function($) {
  var objs = [];

  var defaults = {
       color: "blue",
      normal: "black",
     onHover: function() {},
    offHover: function() {}
  };

  var Text = function (settings, self) {
    this.self     = $(self);
    this.color    = settings.color;
    this.normal   = settings.normal;
    this.show     = function () { this.self.css( "color", this.color); }
    this.noShow   = function () { this.self.css( "color", this.normal);}
    this.onHover  = settings.onHover;
    this.offHover = settings.offHover;
  };

  $.fn.myPlugin = function(opts) {
    this.each(function() {
      var settings = $.extend({}, defaults, opts);

      $(this).data('index', objs.push(new Text(settings, this)) -1);
      // I feel like this should be handled differently, maybe
      // attach an event to the inside of the object?
  });

    this.hover(
      function(e) {
        objs[$(e.currentTarget).data('index')].show();
        objs[$(e.currentTarget).data('index')].onHover();
      }, function(e) {
        objs[$(e.currentTarget).data('index')].noShow();
        objs[$(e.currentTarget).data('index')].offHover();
    });
  };
}(jQuery));

基本上,这一行...

(this).data('index', objs.push(new Text(settings, this)) -1);

...可以以不同的方式处理并且更有效。问题是我需要一个全局数组来保存插件生成的所有对象。因此,如果我在两个单独的 'p' 标记上两次调用插件,那么该数组中应该有两个对象,依此类推。现在,该方面是 'working',但我需要通过将 'index' 数据类型附加到 DOM 元素来存储对该对象所在索引的引用。这感觉是一种非常错误的面向对象方法。那么我怎样才能在事件中触发函数...

myObject.show();

...其中 myObject 是对数组中我要突出显示的元素的引用。

我希望我的问题很清楚,我觉得这是一个奇怪的问题,但如果可以按照我的想法应用它,它也是一个非常强大的概念。如果有任何不清楚的地方,请告诉我,我很乐意澄清。

在阅读更多内容并尝试了解面向对象编程在 javascript、jquery 和 DOM 方面的工作原理时,我偶然发现了自己的答案。对于那些可能像我进入插件开发一样感到困惑的人来说,代码看起来是这样的:

(function($) {
  var defaults = {
       color: "blue",
      normal: "black",
     onHover: function() {},
    offHover: function() {}
  };

  var Text = function(opts, self) {
    var settings  = $.extend({}, defaults, opts);
    this.self     = $(self);
    this.color    = settings.color;
    this.normal   = settings.normal;
    this.onHover  = settings.onHover;
    this.offHover = settings.offHover;
    this.show     = function () { this.self.css( "color", this.color);  };
    this.noShow   = function () { this.self.css( "color", this.normal); };
  };

  $.fn.myPlugin = function(opts) {
    this.each(function() {
      this.text = new Text(opts, this);
    });

    this.hover(
      function() {
        this.text.show();
        this.text.onHover.call();
      }, function() {
        this.text.noShow();
        this.text.offHover.call();
      });
  };
}(jQuery));

我正在处理的问题是对名称 space 和闭包的适当理解,以及对 DOM 元素可以做什么和不能做什么。我不确定这是否是常用方法,但它对我的用途非常有效,可能对您也适用。