“this”的值在使用addEventListener的处理程序中 [英] The value of "this" within the handler using addEventListener

查看:154
本文介绍了“this”的值在使用addEventListener的处理程序中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过原型设计创建了一个javascript对象。我正在尝试动态呈现表格。虽然渲染部分很简单并且工作正常,但我还需要处理动态渲染表的某些客户端事件。那也很容易。我遇到问题的地方是处理事件的函数内部的this引用。它不是this引用对象,而是引用引发事件的元素。

I've created a javascript object via prototyping. I'm trying to render a table dynamically. While the rendering part is simple and works fine, I also need to handle certain client side events for the dynamically rendered table. That, also is easy. Where I'm having issues is with the "this" reference inside of the function that handles the event. Instead of "this" references the object, it's referencing the element that raised the event.

请参阅代码。有问题的区域在ticketTable.prototype.handleCellClick = function()

See code. The problematic area is in "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);
    }


推荐答案

你需要绑定你的实例的处理程序。

You need to "bind" handler to your instance.

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

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

Note that event handler here normalizes event object (passed as a first argument) and invokes handleCellClick in a proper context (i.e. referring to an element that was attached event listener to).

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

Also note that context normalization here (i.e. setting proper this in event handler) creates a circular reference between function used as event handler (onClickBound) and an element object (cell1). In some versions of IE (6 and 7) this can, and probably will, result in a memory leak. This leak in essence is browser failing to release memory on page refresh due to circular reference existing between native and host object.

要规避它,你需要a)放弃这个规范化; b)采用替代(和更复杂)的规范化战略; c)在页面卸载时清理现有的事件监听器,即使用 removeEventListener detachEvent 和元素 null ing(遗憾的是,这会导致浏览器的快速历史导航失效)。

To circumvent it, you would need to either a) drop this normalization; b) employ alternative (and more complex) normalization strategy; c) "clean up" existing event listeners on page unload, i.e. by using removeEventListener, detachEvent and elements nulling (which unfortunately would render browsers' fast history navigation useless).

您还可以找到一个小心的JS库这个的。其中大多数(例如:jQuery,Prototype.js,YUI等)通常处理(c)中描述的清理。

You could also find a JS library that takes care of this. Most of them (e.g.: jQuery, Prototype.js, YUI, etc.) usually handle cleanups as described in (c).

这篇关于“this”的值在使用addEventListener的处理程序中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆