附加和重新附加事件处理程序

时间:2009-08-25 13:30:11

标签: javascript event-handling events

我使用来自框架的事件处理程序(原型是特定的)将listerners附加到页面的某些元素,如下所示:

//html
<a href="?default=1" class="default">Set Default</a>
//js
document.observe('dom:loaded', function(){
        //get all elements with d 'default' classname
        for(i = 0;i < document.getElementsByClassName('default').length;i++)
        {
                s = document.getElementsByClassName('default')[i];
                //attach an onclick event
                s.observe('click', function(e){
                        //prevent the default action (i.e loading the page)
                        e.preventDefault();
                        //read d link attribute
                        ref = this.readAttribute('href');
                        //and now, do it the ajax way
                        new Ajax.Request('js/ajax/handler.php'+ref, {
                                method:'get',
                                onSuccess:function(transport){}
                        });
                });
        }
});

效果很好。真的很好。但是有一个挑战。大多数情况下,这样的操作操纵DOM并且可以添加一个或多个'default'类元素(即另一个Set Default)。这实际上是故意的。但是,新添加的“默认”类元素将不会附加click事件。目前糟糕的工作是再次遍历所有“默认”类并重新附加事件。还有其他想法吗?

2 个答案:

答案 0 :(得分:2)

解决这个问题的通常方法是通过事件委派。如果您将click事件挂钩到包含所有这些.default项的容器上,则可以在该处理程序中进行响应:

document.observe('click', function(event) {
    var elm;

    elm = event.findElement('.default');
    if (elm) {
        // do your nifty stuff with the element
    }
});

如果他们共享一些更高级的容器,则不必是documentEvent#findElement的文档为here

顺便说一句,你的for循环存在很大的性能问题。你在每次迭代时调用document.getElementsByClassName!如果您使用事件委托,那么该循环无论如何都会消失,但如果由于某种原因无效,请将其命名为一次,然后遍历结果:

var defaults = document.getElementsByClassName('default');
for (i = 0; i < defaults.length; i++)

答案 1 :(得分:1)

您可以收听页面上的所有点击事件,然后使用event's target确定用户是否点击了className为“default”的元素。