将事件监听器(在回调函数中)添加到生成的元素中
Adding Event Listeners (in a callback function) to generated elements
我的目标-我想在没有jQuery:的情况下做到这一点
- 从JSON文件中检索数据(ajax GET)
- 使用其中的数据生成链接列表
- 当点击其中一个链接时,获取其id的值(或者可能是另一个属性),使用它来加载相应的数据(来自同一个JSON文件,也通过ajax get)
在重写了这段代码以使用回调之后,我正在获取JSON数据并创建链接。然而,关于addEventListener
的工作方式,我对两件事感到困惑:首先,为什么在for循环中添加事件侦听器时调用showProj
函数(到目前为止,只提醒每个链接的id)?其次,为什么链接在点击后没有响应?我认为添加事件侦听器只是使生成的链接可以点击吗?
function ajaxReq() {
var request = new XMLHttpRequest();
return request;
}
function getJsonData(makeLinks) { // makeLinks = the callback
var request = ajaxReq();
request.open("GET", "/json/projects.json", true);
request.setRequestHeader("content-type", "application/json");
request.send(null);
request.onreadystatechange = function() {
if (request.readyState === 4) {
if (request.status === 200) {
makeLinks(request.responseText);
}
}
} // onreadystatechange
} // getJsonData
getJsonData(makeLinks);
function makeLinks(result) { // result = request.responseText
var projects = JSON.parse(result);
var projects = projects["Projects"];
var projectList = document.getElementById("project-list"); // ul#project-list
for (var project in projects) {
var projectId = projects[project].id;
var listItem = "<li><a class='"project-link'" id='""+projects[project].project+"'" href='"#'">" + projects[project].project + "</a></li>";
projectList.innerHTML += listItem;
}
var projLink = document.getElementsByClassName("project-link");
for (var i = 0; i < projLink.length; i++) {
var projId = projLink[i].id;
projLink[i].addEventListener("click", showProject(projId), false); // ** ?? **
}
} // makeLinks
function showProject(projId) {
/*
function showProject will load data corresponding to the link's id (or another attribute);
presently there are only alerts until the links are working
*/
alert("projId is: " + projId);
} // showProject
同样,我最终想要的只是点击.project-link
类链接,获取其id(或其他一些属性),然后加载相应的数据,例如(伪代码):
projLink.onclick = function(){
var projId = this.id;
showProject(projId);
}
我意识到我可以用这个做到:
$(document).ready(function() {
$("#project-list").on("click", 'li a', function() {
var projId = this.id;
showProject(projId);
})
})
但我想知道为什么事件监听器一开始就不能工作(也就是说,没有jQuery位)。
最后:在这种情况下,通过全局定义var-projLink来排除范围问题,这样我就不必重新定义它,例如在showProj内部,这会被认为是邪恶的坏做法吗?
非常感谢您的任何更正、建议和见解。
var projLink
的作用域是makeLinks()
函数,这是正确的,但更重要的是,它也在Ajax回调中,这是一个单独的异步作用域。
当Ajax代码异步运行时,JS的其余部分也会继续运行。因此,如果您调用另一个函数getElementsByClassName("project-link")
,很可能还没有,因为Ajax回调还没有完成它的工作。
可能的选项包括:
- 将Ajax
request.onreadystatechange()
中的所有内容都放在makeLinks()
中(不理想) - 调整代码以使用单独的回调函数,并将JSON数据传递给它;检查以确保数据被定义&在你尝试采取行动之前先完成
看看前面这个关于Ajax响应的问题。
在进一步阅读了事件监听器之后,我发现了最初两个问题的答案,并解决了当前的问题,因此,如果有人感兴趣:
projLink[i].addEventListener("click", showProject(projId), false);
在上面的语句中调用"showProj"函数是因为i)它(也是)一个回调,如果我理解正确的话,ii)因为提供了一个参数;因此,当for循环中的每个元素都添加了click事件时,就会调用它。显然,如果没有为addEventListener回调提供参数,那么回调函数确实会在单击时调用。[欢迎对此有更多见解]
此外,我了解到第三个参数(布尔值)与capture&冒泡,然而,我现在不会偏离自己的捕获和;起泡。可以说,就我而言,我相当肯定我可以这样满足我的需求:
projLink[i].addEventListener("click", showProject, false);
(甚至可能完全没有可选的布尔值,尽管我的理解是最好将其包括在内(?)
svs,over&出来
- JQuery添加元素需要在我的js之前再次添加JQuery脚本
- 如何使用jquery遍历具有动态添加元素的数组
- jQuery appendTo 替换元素而不是添加元素,如果正在添加的元素预先存在于列表中
- 如何使用jquery添加元素
- 动态添加元素上的 HammerJS
- CSS没有'使用javascript向页面动态添加元素时无法工作
- 使用Javascript在DOM元素中添加元素
- 在添加元素时激发JS事件
- 什么's是在IE8+中添加元素的最有效方法
- d3.js在添加元素时协调
- 使用路由器链接动态添加元素
- 动态添加元素
- 在页面内容完全加载后,使用jQuery在DOM中添加元素
- j查询绑定单击不添加元素
- 在循环 jQuery 上添加元素
- 从一个页面调用 javascript 函数以在第二个页面上添加元素
- 页面加载后向<正文>添加元素时出现问题
- 动态添加元素时刷新 HTML
- 动态添加元素时不触发 JQuery 事件
- 如何使用 JavaScript 获取动态添加元素的宽度