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

查看:32
本文介绍了“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);
}

请注意,这里的事件处理程序规范了 event 对象(作为第一个参数传递)并在适当的上下文中调用 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).

还要注意这里的上下文规范化(即在事件处理程序中设置适当的this)在用作事件处理程序的函数(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) 删除 this 规范化;b) 采用替代的(和更复杂的)规范化策略;c) 在页面卸载时清理"现有的事件侦听器,即通过使用 removeEventListenerdetachEvent 和元素 nulling(不幸的是会渲染浏览器'快速历史导航没用).

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天全站免登陆