用ajax加载的html内容不会检测到其他js函数


Loaded html content with ajax wont detect other js functions

伙计们,我的博客文章列表加载了ajax,在一个div中列出了附加html。这个ajax html结果有一些按钮,需要在点击时执行一些js事件。问题是bcs加载的html结果无法检测到一些事件。。。

使用ajax,我会得到完整的帖子列表,如下面的post-list.php,但当我尝试点击按钮likedislike时,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类。