请查看以下代码段,
我有一个JavaScript类someFunc
的方法someClass
在方法定义内btn
变量的onclick处理程序中,我想同时引用SomeClass
和按钮。
SomeClass.prototype.someFunc = function(){
var btn = document.crealeElement("button");
btn.onclick = function() {
this.somePropertyOfSomeClass = true; //this works, because bind
this.classList.add("active"); //this does not
}.bind(this);
}
我知道,如果我使用bind(this)
,则单击处理程序中的this
变量将指向SomeClass,并且在没有绑定的情况下,它将指向按钮元素。
我的问题是:如何同时获得两者?因为我想要处理程序中的类SomeClass
的某些属性
答案 0 :(得分:3)
访问事件正在通过(currentTarget)冒泡的元素(目标)或当前元素是一种更好,更现代的做法。除类实例外,在类内部是否使用this
尚不清楚。另外,最好使用事件侦听器,以便可以附加相同类型的多个事件。
SomeClass.prototype.someFunc = function(){
const btn = document.crealeElement("button");
btn.addEventListener('click', (event) => {
this.somePropertyOfSomeClass = true; //this works, because arrow function has lexical scope
event.target.classList.add("active"); // proper way to access the element
}
}
另外,您可能想看看ES6类。
答案 1 :(得分:1)
类似的事情应该起作用:
SomeClass.prototype.someFunc = function(){
var that = this;
var btn = document.crealeElement("button");
btn.onclick = function() {
that.somePropertyOfSomeClass = true; //references of SomeClass because of the closure
this.classList.add("active"); //this should reference btn
};
}
另请参阅@Dominic的帖子,这是一个更好的解决方案。
答案 2 :(得分:1)
只需将上下文保存在外部函数中即可:
SomeClass.prototype.someFunc = function(){
let _this = this;
var btn = document.crealeElement("button");
btn.onclick = function() {
_this.somePropertyOfSomeClass = true; //saved context
this.classList.add("active");
}
}
答案 3 :(得分:1)
将此代码this.classList.add("active");
替换为btn.setAttribute("class", "active");
SomeClass.prototype.someFunc = function(){
var btn = document.crealeElement("button");
btn.onclick = function() {
this.somePropertyOfSomeClass = true; //this works, because bind
btn.setAttribute("class", "active"); //this may be help you
}.bind(this);
}
答案 4 :(得分:0)
由于您的代码是根据es5规范编写的,因此一种技术(不使用es6箭头函数,该函数根据定义的位置保留词法this
)将其分配给您外部的变量事件处理程序。 (例如const self = this;
),然后您可以引用self来引用类上的方法,或者引用this
来根据需要触发dom事件的dom元素。由于您将在处理程序之外分配变量,因此变量在分配时将包含this
的值,并且不会由处理程序的执行上下文确定。
注意:addEventListener
是处理事件时的首选,因此您不受每个事件一个处理程序的限制,而是可以将多个处理程序附加到一个事件上。 Assignment via setters将替换之前设置的所有处理程序。
SomeClass.prototype.someFunc = function() {
const self = this;
const btn = document.crealeElement('button');
btn.addEventListener('click', function() {
self.somePropertyOfSomeClass = true;
this.classList.add('active');
});
}
如上所述,您还可以引用处理程序中的特定按钮,并选择不将函数绑定到类的this
值,但这会使处理程序的通用性降低,这意味着只能使用它使用该特定按钮而不是任何按钮。