【问题标题】:JQuery conditional preventDefault() firing when not called未调用时触发 JQuery 条件 preventDefault()
【发布时间】:2016-03-22 10:00:53
【问题描述】:

我编写了以下脚本。

  <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>

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

当我单击一个链接时,它会通过 Ajax 向我触发详细信息,然后它意味着再次“单击”该事件,它确实如此!但该事件不会触发它的正常动作。因此,当单击指向另一个页面的链接时,我会转到另一个页面......这不会发生。

如果我注释掉 event.preventDefault();然后事件按我的预期触发......

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

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

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

【问题讨论】:

  • 看起来您分配给caller 的值不正确,应该是$(this) 而不是this
  • @KallumTanton 谢谢,我已经完成了更新。它的功能仍然相同,(尽管我可以看到现在的对象和以前的字符串之间的区别)但是当我单击链接时它仍然没有将我发送到目的地......
  • 我认为你应该把第一个语句放在“准备好”函数中
  • $(caller).click() 不会重定向到锚目标,如果这是您所要求的。
  • @TolMera 您想在通过 ajax 在服务器上保存点击数据后将用户重定向到链接点击的 href 对吗?

标签: javascript jquery ajax loops preventdefault


【解决方案1】:

你可以试试这个,不用再担心“循环”了:

$(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) 一些链接不需要重定向(如前所述,控制显示/隐藏或文档锚点内的引导模型链接

要纠正这个问题,这实际上取决于具体情况。通常引导程序会向链接添加特定的类或数据属性,以便您可以执行类似的操作。

$('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
      });

【讨论】:

  • 什么是用户一个接一个地点击两个链接并且第一个的ajax响应还没有完成;那么会发生什么?
  • 谢谢!非常直截了当......我想知道一件事,如果用户点击一个不会去任何地方的链接。比如 Bootstrap 模型,或者用于显示/隐藏内容的锚标记,或者实际用作页面中的锚。这会导致页面每次都重新加载吗?
  • @itzmukeshy7 我希望重定向会发生在首先完成的 AJAX 请求上。这并不一定意味着它会是第一个被点击的链接。
  • @TolMera 你有一点链接不会重定向到任何地方我会更新响应。现在关于快速连续多次点击部分,我不知道如何轻松绕过它。
  • @apokryfos @TolMera 为此,我们可以使用async: false 临时阻止浏览器直到ajax 未完成,我们还可以将类添加到a 我们不想重定向到任何地方的元素和在complete 回调中检查此类是否存在;
【解决方案2】:

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

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

需要更改才能检查值:

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

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

【讨论】:

    【解决方案3】:

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

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

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

    所以当第二次点击链接时,我们仍然有complete 方法要执行。一回到ajax调用的complete方法,就发现event1有preventDefault property true,没有重定向。

    【讨论】:

    • 好的 这有点难以理解,但我想我明白了。如果你能解释得更多,那就太好了!或者您是否知道我该如何让它发挥作用?
    【解决方案4】:

    试试这个;)

    $(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;
            }
          }
        });
    
      });
    });
    

    【讨论】:

      猜你喜欢
      • 2011-08-02
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 2012-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多