我正在为一个网络应用程序正在研究一些JS,这是一个令人难以置信的问题。不幸的是,我无法发布完整的代码,因为它是尚未发布的项目的一部分。这个问题让我和我的一些同事难以理解 - 从我能说的,它应该有效。
现在,针对实际问题:用户在某些表单字段中输入一些信息并单击“确认”图像,然后将AJAX请求发送回服务器。服务器执行一些处理,然后发送回状态和一些附加数据的响应。状态消息显示在用户正在使用的模态对话窗口中,并显示带有链接的图标。这是Mootools Request.JSON对象的“onComplete”处理程序,删除了一些错误条件处理:
onComplete: function(response) {
if (response) {
if (response.status == 0) {
// this means the request was successful
licenses = response.licenses;
updateControls();
licenseList();
// here I add the status message...
$("createform_result").innerHTML = "<img src=\'/media/com_supportarea/images/db_success.png\' /> License created. Download:<br /><br />";
// ...and the download "link"
if (response.tlsid) {
$("createform_result").innerHTML += "<a href=\"#\" id=\"newtlslic-"+response.tlsid+"\"><img src=\'/media/com_supportarea/images/download_small.png\' /></a> <em>TLS</em>";
// this line is here for debugging only, to make sure this
// block of code is run (it is) and the element is found (it is)
$("newtlslic-"+response.tlsid).style.border = "1px solid red";
$("newtlslic-"+response.tlsid).addEvent("click", function(e) {
// I've stripped out all other code, also for debugging
e.stop();
});
}
}
}
}
出现带有链接的消息和图标,应用样式(出现红色边框),Firefox或Chrome中不显示任何错误消息。但是,单击该图标会导致将#附加到URL(e.stop())不执行任何操作。根据EventBug插件,链接没有附加点击事件。似乎.addEvent()在这里什么都不做。
现在,他们在这里提出质疑:为什么会这样,我该如何解决?救命啊!
答案 0 :(得分:1)
字符串是不可变的。当你做的事情:
$("createform_result").innerHTML += "<a href=\"#\" id=\"newtlslic-"+response.tlsid+"\"><img src=\'/media/com_supportarea/images/download_small.png\' /></a> <em>TLS</em>";
您将innerHTML引用为字符串。它的作用是,它将属性提取到一个字符串中,将它连接到你传递的其他字符串,然后在最后返回一个新字符串,将其设置为innerHTML。
这样做,每次迭代都会重写元素的内容。
附加到元素的事件不是由通用ID处理程序完成的 - 它们依赖于DOM中的元素,然后正在读取元素UID(内部属性mootools分配给所有传递的元素)并添加事件回调进入UID后面的元素存储。
您可以通过console.log(element.retrieve("events"));
如果重写innerHTML,则重新创建内部元素并获取NEW UID,这意味着回调现在指向空指针,因为UID是元素存储中的键。
我在这里做的事情可能是错的,因为我实际上没有看到你再次重写它的位,但是在你剥离的代码中可能有一个,特别是如果你正在运行一个循环。
处理此问题的最佳方法是使用事件委派。
它可以允许您通过某个选择器将click事件添加到父元素。这适用于任何匹配时以任何方式添加的元素。
例如
// add this once, outside the loop
$("createform_result").addEvent("click:relay(a.editLink)", function(event, element) {
console.log(this === element);
console.log(this === event.target);
console.log(this.get("data-id"));
});
// then as you loop the results, just inject the els or use innerHTML or whatever...
new Element("a.editLink", {
html: '<img src=\'/media/com_supportarea/images/download_small.png\' /></a> <em>TLS</em>',
"data-id": response.tlsid
}).inject($("createform_result"));
事件委托现在是1.4.0中mootools核心的一部分,或者在mootools中 - 在以前的版本中更多。
玩得开心!