我正在尝试使用jQuery Boilerplate编写我的第一个插件。我遇到的问题是,一旦我尝试处理一个事件,我就会失去对this
范围的访问权限,我认为应该variable shadowing。这似乎是jQuery Boilerplate的一个常见用例,所以我猜我错了。
我在SO上发现了两个类似的问题:
我已经创建了一个最小的样本来证明这个问题。
HTML
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
PLUGIN
(function($, window, document, undefined) {
'use strict';
var pluginName = 'elementValueLog',
defaults = {};
function Plugin(element, options) {
this.element = element;
this.$element = $(element);
this.settings = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
$.extend(Plugin.prototype, {
init: function() {
this.$element.on('click', this.doLog);
},
doLog: function() {
// HERE: I can't figure out how to access the Plugin "this" scope
// I want to be able to use "element", "$element", "settings", etc.
console.log(this.$element.val().trim());
}
});
$.fn[pluginName] = function(options) {
this.each(function() {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName, new Plugin(this, options));
}
});
return this;
};
}(jQuery, window, document, undefined));
使用插件
$(document).ready(function() {
$('li').elementValueLog();
});
解
我希望将此作为答案添加,但被标记为“重复”会阻止这种情况。在尝试了另一篇文章的答案中显示的几种方法之后,我找到了一个解决方案。我个人认为我的问题具体到足以独立存在,因为另一篇文章中的“规范”答案相当广泛。
对于browsers that support bind
,init
功能可以像这样更改:
init: function() {
this.$element.on('click', this.doLog.bind(this));
},
因为我需要支持IE 8,所以我将使用jQuery.proxy:
init: function() {
this.$element.on('click', $.proxy(this.doLog, this));
},
doLog
功能可以引用this.element
,this.$element
,this.settings
等。
基于Jeff Watkins的回答:
init: function() {
var plugin = this;
var doLog = function() {
console.log(plugin.$element.val().trim());
};
this.$element.on('click', doLog);
},
此解决方案的好处是可以保留this
上下文,同时可以访问插件的this
上下文。
答案 0 :(得分:1)
&#34;这&#34;是你在堆栈中的位置的上下文,所以&#34;这&#34;在一个事件中实际上是事件,如果这是有道理的。这是一个常见的编程概念。
我经常使用&#34;这个&#34;的高速缓存版本。 (如打电话)如果你需要打电话就可以使用。
即
$.fn[pluginName] = function(options) {
var caller = this;
this.each(function() {
if (!$.data(caller, "plugin_" + pluginName)) {