[英]Javascript attaching event handler in loop
I'm using the loop to create array of elements(links) and then attaching them with event handlers(one function for all) and adding to the DOM.我正在使用循环创建元素数组(链接),然后将它们与事件处理程序(一个函数为所有)附加并添加到 DOM。 But event handler react only then I click on the last link.
但是事件处理程序只有在我点击最后一个链接时才会做出反应。 Code:
代码:
xGetUsers = new XMLHttpRequest();
xGetUsers.open("GET","dialogs.php",true);
xGetUsers.send();
xGetUsers.onreadystatechange = function(){
if (xGetUsers.readyState==4 && xGetUsers.status==200){
var jUsers=eval("("+xGetUsers.responseText+")");
if(jUsers){
var length = jUsers.length;
var dialogLink = [];
for(var i=0; i<length; i++) {
dialogLink[i] = document.createElement("a");
dialogLink[i].innerHTML = "Go dialog";
dialogLink[i].usrn = jUsers[i][0];
dialogLink[i].userID = parseInt(jUsers[i][3]);
dialogLink[i].id = i;
dialogLink[i].onclick = getDialog;
var userinfo = '<div><p>'+jUsers[i][0];
if(jUsers[i][1]!=0) userinfo += '('+jUsers[i][1]+')';
userinfo += '</p><p>'+jUsers[i][2]+'</p></div>';
main_div.innerHTML += userinfo;
main_div.appendChild(dialogLink[i]);
}
}
}
}
}
getDialog() function: getDialog() 函数:
function getDialog(){
enduser_id = this.userID;
enduser_name = this.usrn;
main_div.innerHTML = '<form><textarea id="resz"></textarea><a href="" id="send_button" class="main-button">Send</a></form>';
xLoadMessages.open("GET","get_messages.php?get_id="+enduser_id,true);
xLoadMessages.send();
field = document.getElementById("resz");
document.getElementById("send_button").onclick = function(){
if(field.value!=""){
var message="id="+enduser_id+"&message="+field.value;
xSendMessage.open("POST","add_message.php",true);
xSendMessage.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xSendMessage.send(message);
}
return false;
}
setTimeout(setRefresh, 3000);
return false;
}
It react only on last link.它只对最后一个链接做出反应。 I searched for a long time and tried different ways for adding event handler but nothing helped.
我搜索了很长时间并尝试了不同的方法来添加事件处理程序,但没有任何帮助。 Help please(.
请帮忙(。
I suspect your problem comes from the fact that you create multiple elements with the same ID and then use document.getElementById()
to pick them up.我怀疑您的问题来自这样一个事实:您创建了多个具有相同 ID 的元素,然后使用
document.getElementById()
来获取它们。 Naturally that won't work, your browser decides to give only the last element with that ID.当然这不起作用,您的浏览器决定只给出具有该 ID 的最后一个元素。
More generally speaking you are in need of some modularity in your code.更一般地说,您的代码需要一些模块化。 You need separate functions that deal with Ajax, with user interface building and with user interaction.
您需要处理 Ajax、用户界面构建和用户交互的单独函数。
A very simple implementation of an Ajax interface could look like this: Ajax 接口的一个非常简单的实现可能如下所示:
function http() {}
http.urlEncode = function (data) {
var keys = typeof data === "object" && data ? Object.keys(data) : [],
enc = encodeURIComponent,
result = [], key, val;
if (keys.length && !Array.isArray(data)) {
while (keys.length) {
key = keys.pop();
val = data[key];
if (typeof val === "undefined") continue;
result.push(enc(key) + "=" + enc(val));
}
return result.join("&");
} else if (typeof data !== "undefined") {
return enc("" + data);
}
};
http.request = function (success, error) {
var req = new XMLHttpRequest();
req.onreadystatechange = function () {
if (this.readyState !== 4) return;
if (this.status == 200 && typeof success === "function") success.call(this);
if (this.status != 200 && typeof error === "function") error.call(this);
};
return req;
};
http.get = function (url, data, success, error) {
var req = http.request(success, error);
data = http.urlEncode(data);
req.open("GET", url.replace(/\?.*/, "") + (data ? "?" + data : ""));
req.send();
};
http.post = function (url, data, success, error) {
var req = http.request(success, error);
req.open("POST", url);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.send(http.urlEncode(data));
};
Now you have convenient http.get()
and http.post()
helper functions that accept data and callback parameters.现在您有了方便
http.get()
和http.post()
辅助函数来接受数据和回调参数。
Next you need a function that can build HTML elements, a rudimentary one could look like this:接下来,您需要一个可以构建 HTML 元素的函数,一个基本的函数可能如下所示:
function newElem(source, text) {
var elem;
if (templ.slice(0, 1) === "<") {
elem = document.createElement("div");
elem.innerHTML = source;
elem = elem.firstChild;
} else {
elem = document.createElement(source);
}
elem.textContent = text;
return elem;
}
Based on that you can create a function that builds a user element from what the server returns:基于此,您可以创建一个从服务器返回的内容构建用户元素的函数:
function buildUser(data, getDialogHandler) {
var user, line1, line2, link;
user = newElem("div");
line1 = newElem("p", data[0] + (data[1] ? ' (' + data[1] + ')' : "");
line2 = newElem("p", data[2]);
link = newElem("<a>Go dialog</a>");
link.onclick = function (event) {
getDialogHandler(parseInt(data[3], 10));
};
user.appendChild(line1);
user.appendChild(line2);
user.appendChild(link);
return user;
}
And now you can set up the functions that create your user interface.现在您可以设置创建用户界面的功能。 Note how I completely avoid any global variables or HTML IDs and instead work with DOM object references only.
请注意我是如何完全避免使用任何全局变量或 HTML ID 的,而只使用 DOM 对象引用。
http.get("dialogs.php", null, function () {
var mainDiv = document.getElementById("main_div"),
users;
try {
users = JSON.parse(this.responseText);
users.forEach(function (data) {
var user = buildUser(data, getDialog);
mainDiv.appendChild(user);
});
} catch (ex) {
console.log(ex);
}
});
function getDialog(userId){
var mainDiv = document.getElementById("main_div"),
textArea = newElem("textarea"),
sendBtn = newElem('<a class="main-button">Send</a>');
sendBtn.onclick = function () {
if ( !textArea.value ) return;
http.post("add_message.php", {
id: userId,
message: textArea.value
}, function () {
// whatever you want to do on add_message success
});
return false;
};
mainDiv.innerHTML = "";
mainDiv.appendChild(textArea);
mainDiv.appendChild(sendBtn);
http.get("get_messages.php", {get_id: userId}, function () {
// whatever you want to do on get_messages success
});
// setRefresh is never defined anywhere...
setTimeout(setRefresh, 3000);
}
Notes / Recommendations注释/建议
JSON.parse()
instead of eval()
.JSON.parse()
而不是eval()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.