是否可以使用addEventListener调用类方法?

时间:2014-01-23 03:43:17

标签: javascript

我一直想知道的事情。在.addEventListener方法的第二个参数中,您可以调用“(自定义)类方法”而不是函数吗?

即如下所示?

var object = new ClassName();
document.getElementById('x').addEventListener('click', object.method, false);

6 个答案:

答案 0 :(得分:10)

不,你所写的内容不起作用,因为method将在没有object作为其上下文的情况下被调用。在method内,this将设置为启动事件的DOM元素。

如果要调用方法并保留上下文,请使用函数关闭object变量:

var object = new ClassName();
document.getElementById('x').addEventListener('click', function () {
  object.method()
}, false);

答案 1 :(得分:1)

是。这是可能的,只需要注意上下文。 E.g。

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);

答案 2 :(得分:1)

这里的答案很有帮助,但仍然让我想知道是否有一个整洁的语法基本上做同样的事情。我不想将对类实例的引用传递给它自己,这很奇怪。

这里有一个整洁的模式,它可以保持类中的所有内容,而不需要使用实例引用,而是使用闭包。

myclass= function(){};
myclass.prototype.addSystemEvents = function(){
  var scope = this;
  window.addEventListener( 'resize', function(){scope.onWindowResize();}, false);
}
myclass.prototype.onWindowResize = function(){
   //do whatever
}

答案 3 :(得分:1)

是的,有可能。您需要调用该方法并保留上下文,并使用函数关闭对象变量:

var object = new ClassName();
document.getElementById('x').addEventListener('click', function (e) {
  object.method(e)
}, false);

如果在不使用内部函数的情况下调用,则“ this”将设置为启动事件的DOM元素。

答案 4 :(得分:1)

可以通过绑定来实现。

下面,我正在创建一个 Web 组件。大多数浏览器都支持的一项功能。

为了创建这个 Web 组件,我正在创建一个扩展 HTMLElement 类的类。就 JavaScript 而言,这只是另一个常规类。

现在,我希望我的 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>

答案 5 :(得分:0)

我只是尝试了一种更直接的方法,它似乎有效,而且我会说它非常干净。我只是将 ...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/>`;     
  }
}