场景
在前端开发的时候需要一个场景需要为使用AJax动态加载出来的元素绑定一个popup
事件,但是发现如果直接在js代码中打开要动态加载的元素的popup
的功能无效。
错误复现
原html代码(使用了thymleaf所以javascript的代码内嵌在html里):
<body>
<div id="comment-container">
<div th:fragment="commentList">
<div class="comment" th:each="comment : ${comments}">
<span th:text="${comment.nickname}" class="popupinfo" data-title="Matt" data-content="hello@gmail.com" th:data-title="${comment.nickname}" th:data-content="${comment.email}">Matt</span>
</div>
</div>
<!-- 中间代码... -->
</body>
<script>
$(function() {
$("#comment-container").load(/*[[@{/comments/{id}(id=${blog.blog_id})}]]*/"comments/6");
});
$('.popupinfo').popup({
on : 'hover'
})
</script>
错误逻辑
利用ajax请求服务端拿取comments
,comment-container
里的内容会被.load()
替换,其中class="popupInfo"
的标签的popup
事件被打开,触发条件是hover
。
错误原因
Javascript中未来存在的元素或者说在静态页面下不存在的元素无法在页面加载的时候就为其绑定属性、事件。这里我们在绑定.popupinfo
类元素时,其实它们还不存在,要等异步请求完成并加载到页面上后他们才真正存在,所以这里“并行”的去绑定popup
事件根本不会起作用。这里可以参考一篇分析文章:jquery:为动态加载的元素绑定事件。
解决方案
我的解决方案
在Ajax的回调函数中为元素打开popup
事件,而不是平行于异步Ajax请求:
$(function () {
var url = "/aURL";
$.ajax({
url: url,
contentType: "application/json",
type: "get",
data: "",
success: function f(data) {
$("#aContainer").html(data);
// 在动态元素加载完成,在这里为这些元素绑定打开popup事件
$(".popupinfo").popup({
on : 'click'
});
console.log("成功获取data,并为元素绑定popup()");
}
});
});