jQuery preventDefault() 不适用于 .on()

jQuery preventDefault() not working with .on()

是的,我已经阅读了许多其他有同样问题的帖子,但我不明白如何解决这个问题。我创建了一个书签按钮,它需要在点击时更改图标。

我的jQuery:

jQuery(document).ready( function() {
    
    var bm = jQuery(".user_bookmark");
    
    bm.on("click", ".user_bookmark", function (e) {
        e.preventDefault(); 
        post_id = jQuery(this).attr("data-post_id")
        nonce = jQuery(this).attr("data-nonce")

        jQuery.ajax({
         type : "post",
         dataType : "json",
         url : bookmarkAjax.ajaxurl,
         data : {action: "eri_user_bookmark", post_id : post_id, nonce: nonce},
         success: function(response) {
            if(response.type == "success") {
                var add = 'Add Bookmark';
                var remove = 'Remove Bookmark';
                var display = bm.attr('display');
                var bookmarked = bm.attr('bookmarked');
                if (display == 'icon') {
                    add = '<i class="x-icon" data-x-icon-o="&#xf02e;" aria-hidden="true"></i>';
                    remove = '<i class="x-icon" data-x-icon-s="&#xf02e;" aria-hidden="true"></i>';
                }
                if (bookmarked) {
                    bm.html(remove);
                    bm.attr('bookmarked', 'false');
                } else {
                    bm.html(add);
                    bm.attr('bookmarked', 'true');
                }
            }
            else {
               alert("Your bookmark could not be added")
            }
         }
        })  
    });

})

先是有bm.click(),但只点一下就可以了,后来读到切换到.on()功能,现在正在刷新页面。

我尝试将 function (e) 替换为 function (),并将 e.preventDefault(); 替换为 return false;e.stopImmediatePropagation();e.stopPropagation();

还尝试将 bm.on()jQuery(document).on() 切换为所有这些变体。那仍然是 运行 我的代码并且没有刷新,但它没有更改 jQuery 代码中的元素。

示例HTML:

<a class="user_bookmark" data-nonce="2b92b05de9" data-post_id="1" href="https://example.com/wp-admin/admin-ajax.php?action=eri_user_bookmark&amp;post_id=1&amp;nonce=2b92b05de9" display="icon" bookmarked="true" style="outline: none;">
   <i class="x-icon" data-x-icon-s="" aria-hidden="true"></i>
</a>

完整 PHP 要点:https://gist.github.com/mrgandy/91361fca86e769235eec684a4647b875

问题是因为您不小心嵌套了事件处理程序。您将委托事件处理程序附加到 .user_bookmark,它正在侦听 child .user_bookmark 元素上的点击事件。您的 HTML 显示这些元素未嵌套,因此事件处理程序永远不会触发,因此 preventDefault() 或您的 AJAX 请求都不会被调用。

假设您尝试定位的 <a /> 元素不是动态创建的,则删除您在 on() 调用中使用的第二个参数。

jQuery($ => {
  var $bm = $('.user_bookmark');

  $bm.on('click', function(e) {
    e.preventDefault();
    let post_id = $(this).data('post_id');
    let nonce = $(this).data('nonce');

    console.log(post_id, nonce);
    console.log('ajax request here...');
  });
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="user_bookmark" data-nonce="2b92b05de9" data-post_id="1" href="https://example.com/wp-admin/admin-ajax.php?action=eri_user_bookmark&amp;post_id=1&amp;nonce=2b92b05de9" display="icon" bookmarked="true" style="outline: none;">
  <i class="x-icon" data-x-icon-s="" aria-hidden="true"></i>
  Lorem ipsum
</a>

如果元素实际上是在页面加载后动态添加到 DOM,那么您需要将委托的事件处理程序分配给静态父级,如下所示:

jQuery($ => {
  $(document).on('click', '.user_bookmark', function(e) {
    e.preventDefault();
    let post_id = $(this).data("post_id");
    let nonce = $(this).data("nonce");

    console.log(post_id, nonce);
    console.log('ajax request here...');
  });
})