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)
但这也没有解决问题.
有任何想法吗?
我没有使用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)