0
我一直在試圖學習如何構建jQuery插件,所以我對此仍然陌生。既然這是我的第一個插件,我決定嘗試一個簡單的可摺疊面板/盒子(你只能讀得太多,對吧?)。點擊事件觸發時,我無法訪問對JavaScript類對象的引用。我知道這個事件的內部是指引發事件的元素。我也知道在事件發生前我可以做一些類似_self = this;
的事情,但那隻會緩存集合中的最後一個對象。有沒有人對我如何保持對類對象的引用有任何建議?在Click事件中訪問Javascript類對象
謝謝!
這是我的代碼。
HTML代碼
<div class="mypanel" title="Panel 1">Testing panel 1</div>
<div class="mypanel" title="Panel 2">Testing panel 2</div>
$('.mypanel').collapsiblePanel();
插件代碼
var contentVisible = 'showContent', contentNotVisible = 'hideContent';
;(function($) {
var pluginName = 'collapsibleBox';
function Plugin(element, options) {
this.ele = element;
this.$ele = $(element);
var _self = this;
this.options = $.extend({}, $.fn[pluginName].defaults, options);
this.init();
/* Expose methods of Plugin we wish to be public.
* This gets stored when the plugin is created
*/
return {
option: this.option,
destroy: this.destroy
/* Other public methods here */
}
}
$.fn[pluginName] = function(options) {
/* If the first parameter is a string, treat this as a call to a public method. */
if(typeof arguments[0] === 'string') {
var methodName = arguments[0];
var args = Array.prototype.slice.call(arguments, 1);
var returnVal;
this.each(function() {
/* Check that the element has a plugin instance, and that
* the requrested public method exists.
*/
if($.data(this, 'plugin_' + pluginName) && typeof $.data(this, 'plugin_' + pluginName)[methodName] === 'function') {
/* Call the method of the Plugin instance, and Pass it the supplied arguments */
returnVal = $.data(this, 'plugin_' + pluginName)[methodName].appy(this, args);
}
else {
$.error('Method ' + methodName + ' does not exist on jQuery.' + pluginName);
}
});
if(returnVal !== undefined) {
/* If the method returned something, return it */
return returnVal;
}
else {
/* Otherwise, returning 'this' preserves chainability */
return this;
}
}
/* If the first parameter is an object (options), or was omitted,
* instantiate a new instance of the plugin
*/
else if(typeof options === 'object' || !options) {
return this.each(function() {
/* Only allow the plugin to be instantiated once */
if(!$.data(this, 'plugin_' + pluginName)) {
/* Pass options to Plugin constructor, and store Plugin
* instance in the element's jQuery data object
*/
$.data(this, 'plugin_' + pluginName, new Plugin(this, options));
}
});
}
};
$.fn[pluginName].defaults = {
onInit: function() {},
onDestroy: function() {}
};
Plugin.prototype = {
init: function() {
this.createContentArea();
this.createTitleBar();
this.hook('onInit');
},
createContentArea: function() {
/* ... */
},
createTitleBar: function() {
/* ... */
this.$title.click(function() {
if(this.$ele.data('state') == contentVisible) { // The problem is here
this.collapse();
}
else {
this.expand();
}
});
},
expand: function() {
this.$content.slideDown();
this.$ele.data('state', contentVisible);
},
collapse: function() {
console.log(this);
this.$content.slideUp();
this.$ele.data('state', contentNotVisible);
},
/* Use this function to get/set variables */
option: function (key, val) {
if(val) {
this.options[key] = val;
}
else {
return this.options[key];
}
},
destroy: function() {
/* ... */
},
hook: function (hookName) {
if(this.options[hookName] !== undefined) {
this.options[hookName].call(this.ele);
}
}
};
})(jQuery);
這是一個確定的插件模式? –
從我看過的所有不同的模式中,這是其中之一。如果你有另一種模式的建議,我很樂意嘗試。 – Kyle
我使用[本jQuery教程](http://docs.jquery.com/Plugins/Authoring)中解釋的模式「最佳實踐」模式。你需要投入一些時間來學習它,但我認爲這是一個很好的投資。底部'if(methods [method]){...}'的部分總是相同的,因此您可以自由地編寫這些方法。他們沒有解釋的一點是,你也可以在方法對象外部定義私有變量和私有函數;這可能是有用的。我總是在你的模式中定義私有'var pluginName ='...'',以免在多處寫入插件名稱。 –