具有匿名函数的事件侦听器(typeError,toggle undefined)

时间:2018-04-28 15:41:50

标签: javascript events dom anonymous-function

我是 Javascript 的新手。

我有两张相同的桌子并排放置。我想要一个镜子效果。 case 1可以正常工作,没有匿名功能。

但是,我的case 2 Javascript代码似乎存在一些问题,这对我的项目至关重要


案例1

 var table1td = document.querySelectorAll("#table1 td");
 var table2td = document.querySelectorAll("#table2 td");

 for(var i=0; i<table2td.length; i++)
 {
    table2td[i].addEventListener("click",_click);
 }

 function _click() {
    this.classList.toggle("_changecolor");
 }

案例2

 var table1td = document.querySelectorAll("#table1 td");
 var table2td = document.querySelectorAll("#table2 td");    

 for(var i=0; i<table2td.length; i++)
 {
    table2td[i].addEventListener("click", function(){_click(i)});
 }

function _click(index) {
    this.classList.toggle("_changecolor");
    table2td[9-index].classList.toggle("_changecolor");
}

(HTML,CSS代码无变化)

1 个答案:

答案 0 :(得分:1)

您的代码存在两个问题:

  1. 您无法在this内使用_click,因为它不会成为您的元素。触发事件的元素将绑定到传递给addEventListener的匿名函数,而不是_click(依赖于其余代码,将绑定到undefined或全局对象window)。
  2. 您可以使用this_click从匿名函数中调用Function#call时明确设置Function#apply值来解决此问题:

    for(var i = 0; i < table2td.length; i++) {
        table2td[i].addEventListener("click", function() {
            _click.call(this);                       // passing the current this (of the anonymous function) to _click as we invoke it
        });
    }
    
    function _click() {
        this.classList.toggle("_changecolor");       // using this is OK
    }
    
    1. 由于此famous problem,您无法使用索引。
    2. 快速解决方法是使用let(尊重块范围)而不是var(它不会):

      for(let i = 0; i < table2td.length; i++) {       // using let instead of var
          table2td[i].addEventListener("click", function() { _click(i); });
      }
      
      function _click(index) {                         // using index is also OK
          table2td[index].classList.toggle("_changecolor");
      }