在单个页面中的多个位置使用时,JQuery插件无法正常工作

Jam*_*ell 8 javascript jquery jquery-plugins jquery-boilerplate

我正在为我正在研究的项目编写一个JQuery插件,该项目从桌面设备上的标签内容转变为移动设备上的手风琴.我使用JQuery Boilerplate(https://github.com/jquery-boilerplate/jquery-boilerplate/blob/master/dist/jquery.boilerplate.js)作为我的插件的初始模式.

该插件在具有类".tabs2accordion"的任何元素上调用,如下所示:

 $(".tabs2accordion").tabs2Accordion({state:"desktop"});
Run Code Online (Sandbox Code Playgroud)

如果页面上只有一个带有".tabs2accordion"类的元素,则插件会按预期工作,但只要将具有相同类的另一个元素添加到页面中,该插件就会出现故障.我已经创建了一个基本代码的codepen来演示这个问题.要显示此问题,请在窗口大小> 768px上尝试单击任何标题,并观察下面的内容在单击每个标题时如何更改.接下来取消注释HTML块并尝试再次单击标题.

http://codepen.io/decodedcreative/pen/MyjpRj

我尝试使用类"tabs2accordion"循环遍历每个元素,如下所示:

$(".tabs2accordion").each(function(){
    $(this).tabs2Accordion({state:"desktop"});
});
Run Code Online (Sandbox Code Playgroud)

但这也没有解决问题.

有任何想法吗?

Ste*_* H. 6

我没有使用jQuery Boilerplate,但我相信这里的问题是你的变量调用plugin.

您的代码中没有任何地方声明一个名为的变量plugin.当我停止调试器时Plugin.prototype.showTabContent,我可以评估window.plugin并返回插件的全局值.

在Plugin的构造函数中,第一行读取plugin= this;.由于plugin未定义,因此它在window对象的全局范围内声明变量.

修复是plugin在设置$().on()挂钩时传递对象的引用.传递的数据在事件处理程序中通过属性中event传递的参数data提供.

这是解决方案(http://codepen.io/shhQuiet/pen/JXEjMV)

(function($, window, document, undefined) {
  var pluginName = "tabs2Accordion",
    defaults = {
      menuSelector: ".tabs2accordion-menu",
      tabContentSelector: ".tabs2accordion-content"
    };

  function Plugin(element, options) {
    this.element = element;
    this.$element = $(this.element);
    this.options = $.extend({}, defaults, options);
    this.$menu = $(this.element).find(this.options.menuSelector),
    this.$tabs = $(this.element).find(this.options.tabContentSelector),
    this.$accordionTriggers = $(this.element).find(this.$tabs).find("h3");
    this._defaults = defaults;
    this._name = pluginName;
    this.init();
  }

  Plugin.prototype = {

    init: function() {
      //Set all the tab states to inactive
      this.$tabs.attr("data-active", false);

      //Set the first tab to active
      this.$tabs.first().attr("data-active", true);

      //If you click on a tab, show the corresponding content
      this.$menu.on("click", "li", this, this.showTabContent);

      //Set the dimensions (height) of the plugin
      this.resizeTabs2Accordion({
        data: this
      });

      //If the browser resizes, adjust the dimensions (height) of the plugin
      $(window).on("resize", this, this.resizeTabs2Accordion);

      //Add a loaded class to the plugin which will fade in the plugin's content
      this.$element.addClass("loaded");

      console.log(this.$element);

    },

    resizeTabs2Accordion: function(event) {
      var contentHeight;
      var plugin = event.data;

      if (!plugin.$element.is("[data-nested-menu]")) {
        contentHeight = plugin.$tabs.filter("[data-active='true']").outerHeight() + plugin.$menu.outerHeight();
      } else {
        contentHeight = plugin.$tabs.filter("[data-active='true']").outerHeight();
      }

      plugin.$element.outerHeight(contentHeight);
    },

    showTabContent: function(event) {
      var $target;
      var plugin = event.data;
      plugin.$menu.children().find("a").filter("[data-active='true']").attr("data-active", false);
      plugin.$tabs.filter("[data-active='true']").attr("data-active", false);
      $target = $($(this).children("a").attr("href"));
      $(this).children("a").attr("data-active", true);
      $target.attr("data-active", true);
      plugin.resizeTabs2Accordion({data: plugin});

      return false;
    },

    showAccordionContent: function(event) {
      var plugin = event.data;
      $("[data-active-mobile]").not($(this).parent()).attr("data-active-mobile", false);

      if ($(this).parent().attr("data-active-mobile") === "false") {
        $(this).parent().attr("data-active-mobile", true);
      } else {
        $(this).parent().attr("data-active-mobile", false);
      }
    }

  };

  $.fn[pluginName] = function(options) {
    return this.each(function() {
      if (!$.data(this, "plugin_" + pluginName)) {
        $.data(this, "plugin_" + pluginName, new Plugin(this, options));
      }
    });
  };

})(jQuery, window, document);

$(window).on("load", function() {
  $(".tabs2accordion").tabs2Accordion({
    state: "desktop"
  });
});
Run Code Online (Sandbox Code Playgroud)