【问题标题】:Chrome "onclick" event issueChrome“onclick”事件问题
【发布时间】:2011-11-07 02:27:39
【问题描述】:

好的,所以我正在构建一个应用程序(用于 Chrome(*不是扩展名))并在页面上有一堆重复的元素。所以我决定使用循环动态构建这些元素,如下所示:

for(var i = 1; i <= 64; i++){
    var elem = document.createElement('div');
    elem.id = "element"+i;  
    elem.onclick = "doSomething()"
    $("parentElement").appendChild(elem);
}

当它尝试将我的函数附加到 onclick 事件时,会出现我的问题。当我查看元素时,它上面没有 onclick 属性......即使我单步执行,我也可以到达这条线:

elem.onclick = "doSomething()"

然后我再一步,什么都没有……到目前为止,我已经尝试过带引号和不带引号以及 .onclick 和 .onClick...

提前谢谢你!

【问题讨论】:

    标签: javascript html dom google-chrome


    【解决方案1】:

    您应该始终传递函数本身,而不是任何类型的字符串。

    elem.onclick = doSomething;
    

    这会将doSomething 设置为点击处理程序。

    • 使用字符串会在内部调用eval,这很慢并且可能不安全(后者不适用于此处)。
    • 直接传递函数更直接。
    • 仅当您通过 HTML 设置 onclick 时才需要字符串。

    【讨论】:

    • 谢谢!现在如果我想将参数传递给 doSomthing() 怎么办?我应该只使用一个令人讨厌的功能吗?比如elem.onclick = function(){doSomething(obj.id)}
    • @ThisGuy84:是的,就是这样。
    • 仍然有问题...当我 appendChild 它删除了 onclick 事件!
    • 是的,虽然这更像是我想要做的jsfiddle.net/uM4XN/1 并且它也有效,但是当我简单地在 chrome 中运行我的应用程序时,当我单步执行时,onclick 就在那里,但是当我查看onclick 元素消失了...
    • 好的,我让它工作了...我的 for 循环关闭了一个,所以我没有看到我单击的元素的变化...非常感谢您的帮助! @pimvdb
    【解决方案2】:

    "addEventListener" 是一种更好的方法(如果您想稍后取消绑定/绑定更多事件)。另外,我建议缓存对父元素的引用,像这样

    var docFrag = document.createDocumentFragment(),
        elem;
    for(var i = 1; i <= 64; i++){
        elem = document.createElement('div');
        elem.id = "element"+i;  
        elem.addEventListener('click', doSomething);
        docFrag.appendChild(elem);
    }
    $("parentElement").appendChild(docFrag);
    

    根据列表的大小,您可以考虑事件委托:

    var docFrag = document.createDocumentFragment(),
        elem,
        parent = $("parentElement");
    for(var i = 1; i <= 64; i++){
        elem = document.createElement('div');
        elem.id = "element"+i;
        elem.className = "clickMe";
        docFrag.appendChild(elem);
    }
    parent.appendChild(docFrag);
    parent.addEventListener('click', function( event ) {
        if( event.target.class === 'clickMe' ) {
            doSomething(event);
        }
    });
    

    (类名“clickMe”是完全任意的)

    编辑:这两个示例都落入了 OP 在循环中附加到 DOM 的陷阱。应该尽可能避免这种情况,因为接触 DOM 代价高昂。这些示例已更新为创建一个文档片段,该片段被填充然后附加到父元素。这使得在第一个示例中不需要缓存对父级的引用。

    【讨论】:

    • 我也在研究这条路线!不过我很犹豫,因为我不确定我是否能够传递元素。然而,看起来你刚刚回答了这种恐惧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-02
    • 2014-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多