0

我注意到,当我通过 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 + "__"));

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

4

2 回答 2

1

您正在重写 HTML。.html()返回一个string,然后您对其进行修改并再次设置。浏览器将解析该 HTML 字符串并从中创建新的 DOM 元素。在这个过程中,您破坏了 DOM 元素,从而失去了之前绑定到它们的事件处理程序。

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

this无论您是否修改了它的 HTML 表示,您都在销毁和重新创建内部的每个元素(我假设的每一行)。


你必须解决这个问题:

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

  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;
        });
    });
    

在 JavaScript 中,忘记 HTML 并使用 DOM。

于 2012-12-28T11:33:01.113 回答
0

Chrome 24 中的纯 JavaScript 不会发生这种情况。

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

document.write("<button id='bb'/>")
//undefined
var bb=document.getElementById('bb')
//undefined
bb
//<button id=​"bb">​&lt;/button>​
bb.addEventListener('click',function(){alert('hi');});
//undefined
bb
//<button id=​"bb">​&lt;/button>​
bb.id
//"bb"
bb.id="qq"
//"qq"
bb
//<button id=​"qq">​&lt;/button>​
document.getElementById("bb")
//null
document.getElementById("qq")
//<button id=​"qq">​&lt;/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 更改的方式(可能是无形地破坏对象?)。

于 2012-12-28T00:21:45.507 回答