为什么重命名HTML元素会删除其事件?

时间:2012-12-28 00:13:15

标签: javascript jquery javascript-events

我注意到当我通过javascript更改表单元素的ID或名称时,与之关联的jquery事件不再存在。我已经尝试过使用Firefox 17和IE 10.这是设计的吗?如果是这样,有什么方法可以阻止它吗?

更新:请查看http://jsfiddle.net/qHH7P/2/以获取示例。

我正在添加按钮以通过jquery删除行。当我删除第一行时,我给第二行中的元素一个新名称和ID。然后,该剩余行的删除按钮不再触发该事件。我需要重命名元素,因为ASP.NET MVC在绑定时需要对象集合的某种命名约定。这就是为什么我需要用“0”而不是“1”重命名它们。我正在用

进行重命名
var regexpattern = new RegExp("WorkspaceQuestionSets\\[.+\\]", "g");
$(this).html($(this).html().replace(regexpattern, "WorkspaceQuestionSets[" + index + "]"));
var regexpattern = new RegExp("WorkspaceQuestionSets_.+__", "g");
$(this).html($(this).html().replace(regexpattern, "WorkspaceQuestionSets_" + index + "__"));

我刚刚意识到我甚至没有重命名按钮。因此事件消失的意义更小。但是如果我注释掉重命名元素的代码,事件仍然存在。

2 个答案:

答案 0 :(得分:2)

您正在重写HTML。 .html()会返回字符串,然后您可以对其进行修改和设置。浏览器将解析该HTML字符串并从中创建新的DOM元素。在这个过程中,你破坏了DOM元素并因此松开了之前绑定它们的事件处理程序。

  

我刚刚意识到我甚至没有重命名按钮。因此事件消失的意义就更小了。

无论是否修改了HTML表示,您都在销毁this(我假设的每一行)中的每个元素。


你必须有可能解决这个问题:

  1. 使用事件委托:不是将事件处理程序直接绑定到元素,而是将它们绑定到始终存在的祖先。在.on *[docs]文档的直接和委派事件部分中了解有关事件委派的更多信息。

  2. 不要重写HTML。选择要修改其name属性的元素并对其进行修改。例如:

    var name_exp1 = /WorkspaceQuestionSets\[.+\]/g;
    var name_exp2 = /WorkspaceQuestionSets_.+__/g;
    
    
    sourceEle.closest(".table").find(".row.set").each(function(index) {
        // Edit the name attribute of all `select` and `input` elements
        $(this).find('select, input').prop('name', function(i, name) {
            if (name_exp1.test(name)) {
                return name.replace(
                    name_exp1, 
                    "WorkspaceQuestionSets[" + index + "]"
                );
            }
            else if (name_exp2.test(name)) {
                return name.replace(
                    name_exp1, 
                    "WorkspaceQuestionSets_" + index + "__"
                );
            }
            return name;
        });
    });
    
  3. 在JavaScript中,忘记HTML并使用DOM。

答案 1 :(得分:0)

使用Chrome 24中的纯JavaScript,我不会发生这种情况。

这是我在JS控制台中输入的内容:

document.write("<button id='bb'/>")
//undefined
var bb=document.getElementById('bb')
//undefined
bb
//<button id=​"bb">​</button>​
bb.addEventListener('click',function(){alert('hi');});
//undefined
bb
//<button id=​"bb">​</button>​
bb.id
//"bb"
bb.id="qq"
//"qq"
bb
//<button id=​"qq">​</button>​
document.getElementById("bb")
//null
document.getElementById("qq")
//<button id=​"qq">​</button>​

重要的是,点击该按钮会在分配到bb.id之前和之后触发事件。

同样在Firefox 17中,我没有看到普通JavaScript发生的情况。我在页面上:http://start.ubuntu.com/12.04/Google/?sourceid=hp

在控制台这里发布的是:

[19:29:41.261] var bb=document.getElementById('sbtn')
[19:29:41.267] undefined
[19:29:45.501] bb.addEventListener('click',function(){alert('hi')});
[19:29:45.507] undefined
[19:29:48.292] bb.id
[19:29:48.298] "sbtn"
[19:29:59.613] bb.id="sbttttttn"
[19:29:59.619] "sbttttttn"

id更改后仍然出现警告。

这必须特定于我无法尝试的IE,或jQuery设置事件或处理ID更改的方式(可能无形中破坏对象?)。