Javascript:在课堂上分配onclick

时间:2015-06-30 19:44:00

标签: javascript html class onclick

我创建了一个构造函数来处理自定义列表控件。我创建了一个方法,以允许用户向列表中添加元素,我需要将事件处理程序分配给列表元素(div)的单击事件。

这里是代码的简化版本。列表元素是使用innerHTML属性和字符串模板创建的,我在其上替换特定部分。后来我通过它的id获取元素并在闭包中为它分配一个函数:

function prueba(){
    var plantilla = '<div id="«id»">«texto»</div>';

    var f = function(nombre){
        return function(){console.log('mi nombre es ' + nombre)};
    };

    this.agregar = function(id, texto){
        var tmp = plantilla.replace('«id»', id);
        tmp = tmp.replace('«texto»', texto);
        document.body.innerHTML += tmp;

        document.getElementById(id).onclick = f(id);
    };
};

问题是,显然,事件处理程序未分配给先前创建的div,因此仅由最后一个保留,因为它可以使用以下代码进行测试:

var p = new prueba;

p.agregar('i1', 'texto1');
console.log(document.getElementById('i1').onclick.toString());//shows the function code
p.agregar('i2', 'texto2');
console.log(document.getElementById('i2').onclick.toString());//shows the function code
console.log(document.getElementById('i1').onclick.toString());//returns 'null' error
p.agregar('i3', 'texto3');
console.log(document.getElementById('i3').onclick.toString());//shows the function code
console.log(document.getElementById('i2').onclick.toString());//returns 'null' error

这发生在Iceweasel以及Chromium中。当我在模板中添加'onclick = f(«id»)'时不会发生这种情况(由于指定的函数范围,我不能在这里做),如果我使用document.createElement则不会发生。我做错了什么?

1 个答案:

答案 0 :(得分:1)

您销毁以前创建的元素:

document.body.innerHTML += tmp;

如果要使用HTML标记附加,请使用insertAdjacentHMTL()

document.body.insertAdjacentHTML("beforeend", tmp);

现在不是经历这个破坏性的过程......

  1. 将现有DOM节点序列化为HTML
  2. 将新的HTML片段连接到序列化节点
  3. 销毁旧节点
  4. 使用新节点重新创建节点
  5. ...它只是创建新内容并将其放在body元素结束之前。

    基本上,从您的编码实践中删除element.innerHTML += ...。它从来没有必要,它效率低下,它会导致像你所描述的那样的问题。

    仅供参考,.insertAdjacentHTML()方法接收4种不同的字符串可能性作为第一个参数。每一个都指定一个相对于您调用它的元素的位置。

    字符串是......

    • "beforebegin"
    • "afterbegin"
    • "beforeend"
    • "afterend"

    标签非常明显。它们将新内容定位在当前元素之前,分别位于当前元素的开头,当前元素内部或当前元素之后。

    您的完整代码将如下所示,由于此处不需要tmp,因此我也缩短了一段时间:

    function prueba(){
        var plantilla = '<div id="«id»">«texto»</div>';
    
        var f = function(nombre){
            return function(){console.log('mi nombre es ' + nombre)};
        };
    
        this.agregar = function(id, texto){
            document.body.insertAdjacentHTML("beforeend",
                                                 plantilla.replace('«id»', id)
                                                          .replace('«texto»', texto));
    
            document.getElementById(id).onclick = f(id);
        };
    };