javascript - 无法将脚本绑定(bind)到 DOM 中的新元素

标签 javascript ajax bind

所以我已经研究了一段时间,但我似乎仍然无法弄清楚。

我这里有一个页面:http://taste.fourseasons.com/ingredients/

底部的显示更多按钮使用以下脚本调用页面上的额外帖子:

$("a.view-more").bind('click',function(event){
        event.preventDefault();
        if($('.post-holder').hasClass('ingredients')) { posttype = 'ingredient'; }
        if($('.post-holder').hasClass('recipe')) { posttype = 'recipe'; }
        if($('.post-holder').hasClass('cmed')) { posttype = 'cmed'; }
        filter = 'none';
        morePosts(posttype,filter);
});

让人们投票的选项适用于此:

$.post('http://taste.fourseasons.com/wp-admin/admin-ajax.php', data,
           function(response){
                   if(response!="-1") {
                           el.find('.vote-sm').removeClass('vote-sm').addClass('unvote-sm');
                           el.find('.vote-text').html("VOTED");
                           el.unbind("click");
                           if(response!="null") {
                                   el.find(".vote-count").html(response);
                           }
                           var cookie = getCookie("better_votes_"+postID);
                           if(!cookie) {
                                   var newcookie = postID;
                           } else {
                                   var newcookie = postID;
                           }
                           setCookie("better_votes_"+postID, newcookie, 365);
                   } else {
                   }
           });
           return false;
   });

但是当用户点击显示更多并且这些元素被添加到 DOM 时,投票选项不适用于这些新元素。我以为我可以将它们加在一起:

$("a.view-more").bind('click',function(event){
        event.preventDefault();
        if($('.post-holder').hasClass('ingredients')) { posttype = 'ingredient'; }
        if($('.post-holder').hasClass('recipe')) { posttype = 'recipe'; }
        if($('.post-holder').hasClass('cmed')) { posttype = 'cmed'; }
        filter = 'none';
        morePosts(posttype,filter);

        $(".vote").bind('click',function(event) {
               event.preventDefault();
               postID = $(this).attr('data-post');
               var el = $(this);
               //el.html('<span id="loader"></span>');
               var nonce = $("input#voting_nonce_"+postID).val();
               var data = {
                       action: 'add_votes_options',
                       nonce: nonce,
                       postid: postID,
                       ip: '66.252.149.82'                        
               };
               $.post('http://taste.fourseasons.com/wp-admin/admin-ajax.php', data,
               function(response){
                       if(response!="-1") {
                               el.find('.vote-sm').removeClass('vote-sm').addClass('unvote-sm');
                               el.find('.vote-text').html("VOTED");
                               el.unbind("click");
                               if(response!="null") {
                                       el.find(".vote-count").html(response);
                               }
                               var cookie = getCookie("better_votes_"+postID);
                               if(!cookie) {
                                       var newcookie = postID;
                               } else {
                                       var newcookie = postID;
                               }
                               setCookie("better_votes_"+postID, newcookie, 365);
                       } else {
                       }
               });
               return false;
       });
    });

但这似乎行不通,而且还会产生一种情况,每次投票时都会将两票而不是一票加到总和上。

感谢您的帮助。

此代码来自wp-function页面:

function add_votes_options() {
    $postid = $_POST['postid'];
    $ip = $_POST['ip'];

    if (!wp_verify_nonce($_POST['nonce'], 'voting_nonce_'.$postid))
        return;

    $voter_ips = get_post_meta($postid, "voter_ips", true);
    if(!empty($voter_ips) && in_array($ip, $voter_ips)) {
        echo "null";
        die(0);
    } else {
        $voter_ips[] = $ip;
        update_post_meta($postid, "voter_ips", $voter_ips);
    }   

    $current_votes = get_post_meta($postid, "votes", true);
    $new_votes = intval($current_votes) + 1;
    update_post_meta($postid, "votes", $new_votes);
    $return = $new_votes>1 ? $new_votes : $new_votes;
    echo $return;
    die(0);
}

最佳答案

您遇到了一个相当普遍的事件绑定(bind)问题。

$("a.view-more").bind('click',function(event){

您编写的上述代码行将事件监听器附加到当时可用的 DOM 元素。这就是添加到 DOM 中的新元素不响应事件的原因;因为他们没有附加事件监听器。

为了解决这个问题,我们可以使用一种称为事件委托(delegate)的方法。这通过将事件附加到您想要监听事件的 DOM 元素的父元素来实现。然后,当事件最终传播到父级时,我们可以计算出事件从哪个子级开始。

jQuery 使这很容易做到。您可以使用 delegate() 方法,但我建议您使用 on() 方法,它是处理 jQuery 中所有事件操作的方法。 click()mouseover()bind() 等都是 on() 的别名

无论如何,要委托(delegate)一个事件,我们需要为事件将附加到的父级指定一个选择器,并为我们真正感兴趣的元素指定一个选择器。所以这行代码现在看起来像这样:

$("body").on('click', "a.view-more", function(event){

你真的应该使用 body 以外的东西,但这只是一个例子。

进一步阅读:http://api.jquery.com/on/

关于javascript - 无法将脚本绑定(bind)到 DOM 中的新元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14741799/

相关文章:

javascript - twitter 如何在不重新加载页面的情况下更改 url?

javascript - 如何根据索引删除一行?

javascript - 使用 AJAX 提交两个值

c++ - 使用带有 libcxx 的套接字函数 bind() 编译代码失败

javascript - 有没有更好的方法在 Sails JS 中使用嵌套(关联)模型?

javascript - 选择 jquery 并验证 : validation doesn't work

javascript - 为什么我的 API 调用在 chrome 中有效,但在我的代码中无效?

javascript - AJAX 单页爬取

c++ - 在 sqlite3 语句中绑定(bind) 'unsigned long' (uint64)? C++

asp.net - 如何使用客户端函数 "OnClientClicking"传递绑定(bind)或评估参数