javascript – 在处理程序中使用addEventListener的“this”的值

我已经通过原型创建了一个javascript对象。我试图动态地呈现表。虽然渲染部分很简单,工作正常,但我还需要处理动态渲染表的某些客户端事件。这也很容易。我有问题的是在处理事件的函数中的“this”引用。而不是“this”引用对象,它引用引发事件的元素。

见代码。问题区域在“ticketTable.prototype.handleCellClick = function()”

function ticketTable(ticks)
{
    // tickets is an array
    this.tickets = ticks;
} 

ticketTable.prototype.render = function(element)
    {
        var tbl = document.createElement("table");
        for ( var i = 0; i < this.tickets.length; i++ )
        {
            // create row and cells
            var row = document.createElement("tr");
            var cell1 = document.createElement("td");
            var cell2 = document.createElement("td");

            // add text to the cells
            cell1.appendChild(document.createTextNode(i));
            cell2.appendChild(document.createTextNode(this.tickets[i]));

            // handle clicks to the first cell.
            // FYI, this only works in FF, need a little more code for IE
            cell1.addEventListener("click", this.handleCellClick, false);

            // add cells to row
            row.appendChild(cell1);
            row.appendChild(cell2);


            // add row to table
            tbl.appendChild(row);            
        }

        // Add table to the page
        element.appendChild(tbl);
    }

    ticketTable.prototype.handleCellClick = function()
    {
        // PROBLEM!!!  in the context of this function, 
        // when used to handle an event, 
        // "this" is the element that triggered the event.

        // this works fine
        alert(this.innerHTML);

        // this does not.  I can't seem to figure out the syntax to access the array in the object.
        alert(this.tickets.length);
    }
你需要“绑定”处理程序到你的实例。

var _this = this;
function onClickBound(e) {
  _this.handleCellClick.call(cell1, e || window.event);
}
if (cell1.addEventListener) {
  cell1.addEventListener("click", onClickBound, false);
}
else if (cell1.attachEvent) {
  cell1.attachEvent("onclick", onClickBound);
}

注意,事件处理程序在这里规范化事件对象(作为第一个参数传递),并在适当的上下文中调用handleCellClick(即引用附加事件监听器的元素)。

还要注意,这里的上下文标准化(即在事件处理程序中设置正确的)在用作事件处理程序(onClickBound)和元素对象(cell1)的函数之间创建一个循环引用。在IE(6和7)的某些版本中,这可能,并且可能会导致内存泄漏。这种泄漏本质上是由于本地和主机对象之间存在循环引用,浏览器无法在页刷新时释放内存。

为了规避它,你需要a)删除这个规范化; b)采用替代(和更复杂)的归一化策略; c)在页面卸载时“清理”现有的事件监听器,即通过使用removeEventListener,detachEvent和元素nulling(不幸的是会使浏览器的快速历史导航无用)。

你也可以找到一个JS库来处理这个。他们中的大多数(例如:jQuery,Prototype.js,YUI等)通常处理清理,如(c)中所述。

http://stackoverflow.com/questions/1338599/the-value-of-this-within-the-handler-using-addeventlistener

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:javascript – 在处理程序中使用addEventListener的“this”的值