簡體   English   中英

是否可以使用 addEventListener 調用 class 方法?

[英]Is it possible to call a class method with addEventListener?

只是我一直想知道的事情。 在 .addEventListener 方法的第二個參數中,可以調用“(自定義) .addEventListener方法”而不是 function 嗎?

即會像以下工作嗎?

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

不,您編寫的內容不起作用,因為該method將在沒有object作為其上下文的情況下被調用。 method內部, this將被設置為啟動事件的 DOM 元素。

如果要調用該方法並保留上下文,請使用函數關閉object變量:

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

我只是嘗試了一種更直接的方法,它似乎有效,我會說它很干凈。 我只是將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/>`;     
  }
}

是的。 有可能,只要注意上下文。 例如

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

這里的答案很有幫助,但仍然讓我想知道是否有一個整潔的語法可以做基本相同的事情。 我不想將類實例的引用傳遞給它自己,這很奇怪。

這是一個整潔的模式,它將所有內容都保留在類中,無需使用實例引用,而是使用閉包。

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 組件,我創建了一個擴展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);

現在,當您在方法onClick中使用this關鍵字時, 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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM