JQuery 有条件的 preventDefault() 在未调用时触发

JQuery conditional preventDefault() firing when not called

我编写了以下脚本。

  <script>
    $(document).ready(function(){
      $('a').data('loop',true);
      $('body').on('click', 'a', function(event){
        console.log($(this).data('loop'));
        if ($(this).data('loop') == 'true') {
          console.log('hit');
          event.preventDefault();
          caller = $(this);
          $(this).data('loop',false);
          var linkref = $(this).attr('href');
          var linkpos = $(this).offset();
          var screenwidth = $(window).width();
          var json_data = JSON.stringify({linkref: linkref, linkpos: linkpos, screenwidth: screenwidth});
          $.ajax({
            url: "content/submitcontenthandler?handler=core/_dashboard&method=tracking_ping",
            method: "POST",
            data: "json=" + json_data,
            complete: function (jqXHR, status) {
              console.log(status);
              console.log(caller);
              $(caller).click();
            }
          });
        } else {
          console.log(event.isDefaultPrevented());
          console.log('miss');
          $(this).data('loop',true);
        } 
      });
    });
  </script>

它有效,向我发送了我想要的详细信息等等。但是!!!

当我单击 link 时,它会通过 Ajax 向我发送详细信息,然后它会再次 "click" 事件,它确实如此!但事件不会触发它的正常操作。因此,当单击 link 到另一个页面时,我会转到另一个页面...这没有发生。

如果我注释掉 event.preventDefault();然后事件如我所料触发...

所以对我来说,看起来 event.preventDefault 正在执行,即使它不应该在第二次调用期间...

抱歉,如果这有点难以理解。我不太明白自己发生了什么。 这可能是一个错误,还是我所做的事情导致了这个问题?

我认为我做不到,但我已经成功地为此制作了一个 jsfiddle。 https://jsfiddle.net/atg5m6ym/2001/

只要元素存在 data-loop 属性,无论其值如何,以下 if 语句都会 return 为真:

if ($(this).data('loop')) {

需要更改以检查值:

if ($(this).data('loop') == 'true') {

当您将任何内容指定为元素属性的值时,它会变成一个字符串,因此需要进行字符串比较。

Event.preventDefault()没有被执行第二次。

Link 重定向发生在方法完成时。 因此,在您的情况下,当 ajax 调用的 complete 方法完成时,将发生重定向。

假设,我们在代码中有 event1 和 event2 对象。 event1是ajax调用方法中的对象,event2是递归调用(二次调用)方法中的事件对象。

所以当link被第二次点击时,我们还有complete方法要执行。一旦它 returns 调用 ajax 的 complete 方法,它发现 event1 有 preventDefault property true 并且它没有重定向。

你可以试试这个,不用再担心 "loop":

$(document).ready(function () {
    $('body').on('click', 'a', function (event) {
        event.preventDefault();
        var caller = $(this);
        var linkref = $(this).attr('href');
        var linkpos = $(this).offset();
        var screenwidth = $(window).width();
        var json_data = JSON.stringify({linkref: linkref, linkpos: linkpos, screenwidth: screenwidth});
        $.ajax({
            url: "content/submitcontenthandler?handler=core/_dashboard&method=tracking_ping",
            method: "POST",
            data: "json=" + json_data,
            complete: function (jqXHR, status) {
                console.log(status);
                console.log(caller);
                window.location.href = linkref; // Redirect happens here
            }
        });

    });
});

更新

这里有几个问题需要注意:

1) 一些链接不需要重定向(如前所述,bootstrap 模型链接控制 showing/hiding 或文档锚

要更正此问题,这实际上取决于具体情况。通常 bootstrap 会向链接添加特定的 类 或数据属性,这样您就可以执行类似的操作。

$('body').on('click', 'a:not(list of things to exclude)'..

我个人会将要跟踪的链接定义为:

<a href=<link> data-tracked='true'...

<script> 
      $('body').on("click","a[data-tracked='true']"...

或者,如果您想跟踪除少数例外的大多数链接,您可以:

     <a href=<link> data-tracked='false'...
     <script> 
          $('body').on("click","a:not([data-tracked='false'])"...

或者更一般地说:

 <script> 
      $('body').on("click","a", function () {
            if ($(this).attr("data-tracked") == "false" || <you can check more things here>){ 
                  return true; //Click passes through
             } 
             //Rest of the tracking code here
      });

试试这个 ;)

$(document).ready(function(){
  $('body').on('click', 'a', function(event){
    event.preventDefault();

    var caller = $(this);
    var linkref = $(this).attr('href');
    var linkpos = $(this).offset();
    var screenwidth = $(window).width();

    var json_data = JSON.stringify({
      linkref: linkref,
      linkpos: linkpos,
      screenwidth: screenwidth
    });

    $.ajax({
      url: "content/submitcontenthandler?handler=core/_dashboard&method=tracking_ping",
      method: "POST",
      /* To temprary block browser; */
      async: false,
      data: "json=" + json_data,
      complete: function(jqXHR, status){
        /* add class **ignore** to a element you don't want to redirect anywhere(tabs, modals, dropdowns, etc); */
        if(!caller.hasClass('ignore')){
          /* Redirect happens here */
          window.location.href = linkref;
        }
      }
    });

  });
});