提问人:Azrael 提问时间:1/23/2014 最后编辑:Azrael 更新时间:3/7/2023 访问量:29089
是否可以使用 addEventListener 调用类方法?
Is it possible to call a class method with addEventListener?
问:
只是我一直在想的事情。在方法的第二个参数中,是否可以调用“(自定义)类方法”而不是函数?.addEventListener
即像下面这样的东西会起作用吗?
var object = new ClassName();
document.getElementById('x').addEventListener('click', object.method, false);
答:
是的。这是可能的,只要注意上下文即可。F.D.(英语:F.D.)
ClassName.prototype.click_handler = function(el) {
// Here 'this' doesn't refer to the instance
// of ClassName but to the element clicked
}
var object = new ClassName();
document.getElementById('x').addEventListener('click', object.click_handler, false);
评论
不,你写的东西是行不通的,因为如果没有上下文,就会被调用。在里面,将设置为启动事件的 DOM 元素。method
object
method
this
如果要调用该方法并保留上下文,请使用函数关闭变量:object
var object = new ClassName();
document.getElementById('x').addEventListener('click', function () {
object.method()
}, false);
评论
这里的答案很有帮助,但仍然让我想知道是否有一种整洁的语法可以做基本相同的事情。我不想将对类实例的引用传递给它自己,这很奇怪。
这是一个整洁的模式,它将所有内容保留在类中,无需使用实例引用,而是使用闭包。
myclass= function(){};
myclass.prototype.addSystemEvents = function(){
var scope = this;
window.addEventListener( 'resize', function(){scope.onWindowResize();}, false);
}
myclass.prototype.onWindowResize = function(){
//do whatever
}
评论
是的,这是可能的。您需要调用该方法并保留上下文,使用函数关闭对象变量:
var object = new ClassName();
document.getElementById('x').addEventListener('click', function (e) {
object.method(e)
}, false);
如果您在没有内部函数的情况下调用,则“this”将被设置为启动事件的 DOM 元素。
评论
是的,通过执行绑定是可能的。
下面,我将创建一个 Web 组件。大多数浏览器都支持的功能。
为了创建此 Web 组件,我正在创建一个扩展该类的类。就 JavaScript 而言,这只是另一个常规类。HTMLElement
现在,我希望我的 Web 组件像按钮一样运行。 我希望每次点击我的标签时增加一个计数器。
注意:这三个点表示“更多代码”到达那里。
因此,我创建了一个变量,该变量将在构造函数中保存计数:
constructor(){
...
this.count = 0;
...
然后,我添加一个侦听器,用于检测何时单击我的 Web 组件并调用该方法:onClick
constructor(){
...
this.count = 0;
...
this.addEventListener('click', this.onClick, false);
}
onClick(event){
let prevCount = this.count;
this.count++;
let msg = `Increased Count from ${prevCount} to ${this.count}`;
document.getElementById("log").innerHTML += `${msg}<br/>`;
}
onClick 旨在增加计数器并在计数器中打印上一个值和当前值;但是,这里有一个问题!!
问题出在这一行.关键字不是指类的实例。原因是添加的函数会将绑定元素引用为 ,而不是函数或对象。this.count++;
this
HTMLExample
addEventListener
this
因此,您必须通过添加以下代码行来绑定该函数,该函数由 用于类的实例:addEventListener
this.onClick = this.onClick.bind(this);
现在,当您在方法中使用关键字时,将引用类的实例。this
onClick
this
HTMLExample
请检查下面的代码并运行它。我认为这样会变得很清楚:
class HTMLExample extends HTMLElement{
constructor(){
super();
this.count = 0;
this.onClick = this.onClick.bind(this);
this.addEventListener('click', this.onClick, false);
}
onClick(event){
let prevCount = this.count;
this.count++;
let msg = `Increased Count from ${prevCount} to ${this.count}`;
document.getElementById("log").innerHTML += `${msg}<br/>`;
}
}
customElements.define('example-component', HTMLExample);
example-component{
cursor: pointer;
border: 1px solid black;
background: lightgray;
padding: 2px;
}
<example-component>Button</example-component>
<div id="log"></div>
我只是尝试了一种更直接的方法,它似乎有效,我会说它很干净。我只是将参数添加到 .不要让它变得复杂,当它不是......bind(this)
addEventListener()
class HTMLExample extends HTMLElement{
constructor(){
super();
this.count = 0;
this.addEventListener('click', this.onClick.bind(this), false);
}
onClick(event){
let prevCount = this.count;
this.count++;
let msg = `Increased Count from ${prevCount} to ${this.count}`;
document.getElementById("log").innerHTML += `${msg}<br/>`;
}
}
对于任何使用打字稿或 Babel/Transpilation 的人来说,这是我能想到的最干净的方法,我相信还有改进的余地!
class Person {
name = "bobby"
sayGoodbyBound = this.sayGoodby.bind(this);
sayGoodby() {
console.log('Goodbye, my name is', this.name);
}
}
const person = new Person();
let element = document.createElement("button")
element.addEventListener("click", person.sayGoodbyBound);
element.click()
// remove same one
element.removeEventListener("click", person.sayGoodbyBound);
大多数答案都使用 Function.prototype.bind(),但您可以通过简单地编写来实现它。
class EventHandler {
constructor(element) {
element.addEventListener('mousedown', this.handler);
}
// just declare the method as a property with arrow function.
hander = () => {
console.log(this);
}
}
我在 codepen.io 编写了完整的工作代码示例。
评论
method
.method
object.method
addEventListener
function foo() {...}; obj.method = foo; obj2.method2 = foo; var bar = foo;
foo