jQuery 插件开发如何保持变量和方法的私密性
jQuery Plugin Development how to keep variables and methods private
出于练习目的,我正在创建一个jQuery插件,一个简单的图像滑块。我使用来自样板的模式 - jQuery 插件。
在初始化过程中,一切都按预期工作,每个实例都会获得设置所需的正确值(宽度和高度,以及事件绑定)。
当我尝试将计算出的幻灯片宽度传递给执行动画的函数(单击下一步按钮)时,麻烦就开始了。我尝试保存的每个值都被最后一个实例覆盖 - 好吧,这就是原型继承的作用,正如我所了解的。
我用谷歌搜索了很多,发现(不仅)这个解决方案在 stockoverflow 上:jquery-plugin 中的全局或局部变量。接受的答案建议将需要私有的值存储在HTML标记中,即data-what属性。
这很好用,但不是很好。
第二个答案似乎更优雅,将真正的私有变量保留在每个实例的范围内:
(function($) {
$.pluginName = function(element, options) {
....
var plugin = this;
....
// a public method
plugin.foo_public_method = function() {
....
}
// private methods
var foo_private_method = function() {
....
}
plugin.init();
} ....
看起来很简单 - 但我无法实现这个解决方案!
所以我的问题是:如何在以下插件模式中实现私有变量?(以及如何从插件原型内部正确调用它......
我用我的插件创建了一个小提琴。代码摘要:
(function ($, window, document, undefined) {
var pluginName = "easyCarousel";
// default configuration object
defaults = {
... default values here, css etc
}
};
// The actual plugin constructor
function Plugin(element, options) {
this.element = element;
this.options = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype = {
init: function () {
var options = this.options;
this.options.stage = $(this.element);
.... calling/starting views and controllers
},
buildCollectionView: function (options, Helper) {
.... setting markup, applying css, calulating dimensions
},
buildStageView: function (options, Helper) {
.... setting markup, applying css
.... storing calculated slide width in data Attribute
stage.attr({
'data-slidewidth': width,
'data-stagewidth': setWidth
});
},
buildTheatreView: function (options, Helper) {
.... setting markup, applying css
},
buildNavigationView: function (options) {
.... setting markup
},
navigationController:
function (options, slideForward, slideBackward) {
.... event binding
pubSub.on("navigation:arrownext:click", function (e) {
slideForward(options, e);
});
$('.carousel__arrownext', options.theatre)
.bind('click', function () {
pubSub.trigger("navigation:arrownext:click", this);
});
},
slideForwardAnimation: function (options, e) {
.... reading stored width value from data Attribute
$element.animate({
"left": "-=" + slideWidth
})
},
setDimensionsHelper: function (options) {
.... calculating an returning dimensions of the slider
},
eventBusHelper: function (options) {
// integrating third party eventbus
}
};
$.fn[pluginName] = function (options) {
return this.each(function () {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName,
new Plugin(this, options));
}
});
}})(jQuery, window, document);
我希望我的代码示例不是复杂/长视图。
正如你可能看到的,我对高级Javascript模式很陌生 - 现在我真的卡住了。我已经在这个问题上花了很多时间。因此,非常感谢我们每一次提供帮助的尝试。当然,每次对代码的审查也是如此。
提前致谢:)
您需要做的就是在原型中定义变量(直接或从原型中的方法中定义变量),而不是在构造函数中执行此操作。构造函数中定义的变量将在插件的所有实例之间共享,而原型中定义的变量将按实例共享。
此外,在"defaults"定义前面没有"var"关键字,因此您实际上是在创建一个名为"defaults"的全局变量,而不是一个范围仅限于闭包的全局变量。
这是我的建议:
// default configuration object
var defaults = {
... default values here, css etc
}
};
// The actual plugin constructor
function Plugin(element, options) {
this._defaults = defaults;
this._name = pluginName;
this.init(element, options);
}
Plugin.prototype = {
init: function (element, options) {
this.element = element;
this.options = $.extend({}, this._defaults, options);
this.options.stage = $(this.element);
.... calling/starting views and controllers
},
甚至更好:
// The actual plugin constructor
function Plugin(element, options) {
this.init(element, options);
}
Plugin.prototype = {
_name: 'put your name here',
_defaults: {
// just define them here, no need for an outside variable
},
init: function (element, options) {
this.element = element;
this.options = $.extend({}, this._defaults, options);
// why are you saving stage as an option? That doesn't make sense.
this.options.stage = $(this.element);
// Makes more sense to just do this ($el is a more standard name for this)
this.$el = $(this.element);
// .... calling/starting views and controllers
},
- electronic BrowserWindow的最小高度和宽度在hide()show()方法之后不起作用
- 有没有任何方法可以将控制器从文件加载到ui路由器$stateProvider中
- 数组在递归方法中设置为null
- 打破承诺链的好方法是什么
- 在使用Polymer'加载所有json文件后执行方法;s的核心ajax
- 使用“;这个“;JavaScript原型方法中的关键字
- 序列化数据属性中对象的最可靠方法
- 使用Objective-C的JavaScript注入方法
- 有没有一种方法可以添加相同的项目val=“0”;4〃;到JavaScript中数组的每个对象
- 有没有一种方法可以防止img get请求使用css或js发生
- Javascript,有没有一种方法可以将数组写成没有逗号或空格的单个文本字符串
- toBoolean方法类似于toString
- 如何在单击复选框后调用控制器方法
- 是否有任何方法可以使用jQuery替换在数组中定义值的文本
- 递归使用 eval() 是检查程序执行的好方法吗?
- 如何在webView,Android中从@JavascriptInterface方法调用Javascript
- toLocaleDateString和toLocaleString方法不尊重机器时区
- 有条件更新d3.js力图中节点的最佳方法
- TypeError:在不兼容的接收器nodejs上调用了方法Uint8Array.length
- jQuery 插件开发如何保持变量和方法的私密性