如何为XMLHttpRequest动态加载的DOM节点添加EventListener事件监听器
网页端文件管理器动态节点绑定事件问题解决
问题场景
开发网页端文件管理器时,通过XMLHttpRequest请求获取当前目录下的所有文件并渲染到HTML页面中,遇到动态渲染完成的节点无法绑定事件监听器的问题:异步XMLHttpRequest请求的执行完成时机始终晚于预设的绑定事件监听器的时机。
问题代码
$(window).on("load", function() { // 初始化ajax请求 let ajax = new XMLHttpRequest(); let methode = "GET"; let url = "php/getFile.php" let asynchronous = true; ajax.open(methode, url, asynchronous); ajax.send(); let data; ajax.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { let data = JSON.parse(this.responseText); let files = ` <ul data-role="listview" data-view="list" data-select-node="true"> <ListView ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollMode="Enabled" >`; for (let i = 0; i < data.length; i++) { let file = data[i]; let nom = file['file']; let ext = "." + file['ext']; let nudeExt = file['ext']; files += `<li id="test" data-icon="<span class='mif-document-file-${nudeExt.toLowerCase()}'>" data-caption="${nom}"></li>` } files += ` </ul>`; document.querySelector("#files").innerHTML = files; // 此处绑定事件不生效 document.querySelector("#test").addEventListener("onclick", test()); } } }) function test() { let test = document.querySelector('#test'); console.log(test) }
错误原因
原有绑定事件的写法存在3处问题:
addEventListener方法的第一个参数为事件名,不需要加on前缀,点击事件对应的参数应为click而非onclick- 传入回调函数时直接写函数名即可,添加括号会导致函数立即执行,不会作为事件触发时的回调绑定
- 循环生成
<li>节点时重复使用了同一个idtest,id属性具有唯一性,重复id会导致选择器仅能匹配到第一个生成的节点
最终解决方案
放弃直接通过addEventListener绑定的写法,改为在生成节点时直接内嵌事件绑定,代码如下:
files += `<li ondblclick="test()" class="folder" type="folder" data-icon="<span class='mif-folder'>" data-caption="${nom}"></li>`
内容的提问来源于stack exchange,提问作者PascheK7
相关产品推荐
相关产品推荐

