jQuery 样板 - 失去对“this”作用域的访问权限
jQuery Boilerplate - Losing Access to "this" Scope
我正在尝试使用jQuery样板编写我的第一个插件。我遇到的问题是,一旦我尝试处理事件,我就会失去对this
范围的访问权限,我认为这是由于可变阴影。这似乎是jQuery样板的一个常见用例,所以我猜我做错了。
我在SO上发现了两个类似的问题:
- jQuery插件对象:通过.on((附加了一个事件处理程序,现在有一个范围问题。(主插件对象( - 没有答案
- 使用 JQuery 样板的 Javascript 范围界定问题 - 没有回答我的问题
我创建了一个最小的示例来演示该问题。
.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();
});
溶液
我更愿意将其添加为答案,但被标记为"重复"会阻止这一点。在尝试了另一篇文章答案中显示的几种方法后,我找到了解决方案。我个人认为我的问题足够具体,可以独立存在,因为另一个帖子的"规范"答案相当广泛。
对于支持 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
等。
根据杰夫·沃特金斯的回答:
init: function() {
var plugin = this;
var doLog = function() {
console.log(plugin.$element.val().trim());
};
this.$element.on('click', doLog);
},
此解决方案的优点是保留this
上下文,同时允许访问插件的this
上下文。
">
this"与你在堆栈中的位置相关,所以事件中的"this"实际上是事件,如果这有意义的话。这是一个常见的编程概念。
我经常使用缓存版本的"this"(即调用者(来使用,如果你需要调用它的东西。
即
$.fn[pluginName] = function(options) {
var caller = this;
this.each(function() {
if (!$.data(caller, "plugin_" + pluginName)) {
相关文章:
- 从ng模板访问作用域
- 访问多个指令的隔离作用域
- 如何在隔离作用域指令中访问此作用域变量
- 访问Javascript对象-Node.js的作用域问题
- 当指令中已经给定作用域时,如何访问控制器中声明的函数
- 插槽:访问作用域变量
- 从ES6中的函数表达式访问类作用域
- 跨不同作用域访问函数
- AngularJS$作用域在函数之外不可访问
- 使用模块模式时访问父作用域中的变量
- 从jQuery.ech()函数访问外部作用域
- 以新模式访问作用域形式ng repeat
- 作用域访问-Javascript
- 如何从全局作用域访问函数中的变量?
- 如何从不同的对象作用域访问可观察对象
- 如何从两次或三次嵌套的ng-repeat作用域访问控制器的作用域
- 我如何从上层作用域访问变量- javascript
- 从外部(即定义闭包的作用域)访问闭包内部定义的var
- 从内部函数的父作用域访问数组元素
- 从指令作用域访问Angular工厂