伙计们,我的博客文章列表加载了ajax,在一个div中列出了附加html。这个ajax html结果有一些按钮,需要在点击时执行一些js事件。问题是bcs加载的html结果无法检测到一些事件。。。
使用ajax,我会得到完整的帖子列表,如下面的post-list.php
,但当我尝试点击按钮like
或dislike
时,ajax结果事件不会被触发,因为所有功能都在一个文件中。我用萤火虫检查他只检测到listPosts()
的功能。
参见示例:在我的索引中加载了这个结果:
post-list.php文件
<!-- List of post loaded from db (LOOP)
<h1>Post title</h1>
<p> Post content </p>
<button id="like">Like</button> <!-- jquery click event need to be fired but wont -->
<button id="dislike">Dislike</button> <!-- the some -->
脚本示例:
var Post = {
addPost: function() {
// Ajax req for insert new post
}
listPosts: function() {
// Ajax req for fetching posts
}
likePost: function() {
// example
$("#like").click(function() {
console.log("liked") // debug
$.ajax() // etc;
});
dislikePost: function(obj) {
// the some
});
init: functon() {
Post.addPost();
Post.listPosts();
Post.likePost();
Post.dislikePost();
}
}
Post.init();
这个脚本用ajax加载所有帖子,在某个事件上添加新帖子,在db中发送like结果和不喜欢的结果。所以在这个帖子列表的结果中,当我尝试点击喜欢或不喜欢按钮时,什么都没有发生。
只有当我这样做时才有效:
<button id="like" onclick="Post.likePost(this);">Like</button>
但是我不想这样做。我不理解脚本检测listPosts()
,但不会检测ajax响应中的其他函数。
事件冒泡。
委派事件的优势在于,它们可以从以后添加到文档中的子元素。通过选择保证在已附加委托事件处理程序,可以使用委托事件避免了频繁附加和删除事件处理程序的需要。这元素可以是例如,如果事件处理程序希望监视文档中的所有冒泡事件。这个document元素在之前的文档标题中可用加载任何其他HTML,因此在没有等待文档准备就绪。
$('#container-div').on('click', '#like', function() {
console.log('Liked');
});
如果您有一个静态container-div
,它将使其中的所有事件冒泡,即它可以看到由动态创建的对象引起的任何事件。
我建议使用类名,而不是重复相同的id:
<button class="like">Like</button>
<button class="dislike">Dislike</button>
现在您可以将事件委托给静态父元素:
$('staticParent').on('click', '.like', Post.likePost)
.on('click', '.dislike', Post.dislikePost);
其中$('staticParent')
将是容纳按钮的容器元素,并且它在posts加载之前就在那里。虽然您也可以用$(document)
替换它,但从document
查找可能会使事件执行有点慢。
这个问题的解决方案是使用"事件委派"。这是一个非常强大的功能,允许您使用事件处理程序,而无需将它们显式附加到元素或元素组。这是一个例子:
$('#like').on('click',handleLike);
这意味着任何与选择器匹配的东西都将触发回调。此外,我建议从使用id改为更通用的东西,比如CSS类。