jQuery preventDefault()不能像我期望的那样工作 - 这是一个jQuery Bug吗?

时间:2011-12-05 16:55:47

标签: javascript jquery javascript-events javascript-framework

这是简化的代码,可以准确地重现我在使用jQuery时遇到的问题。

我希望它取消原始点击,然后再次触发点击事件,这反过来会导致浏览器加载网址的href。

<script type="text/javascript">
$( function()
{
    var confirmed = false;
    $('a').click( function( event )
    {
        if ( confirmed == false )
        {
            event.preventDefault();
            confirmed = true;
            $(event.target).trigger( 'click' );
        }
    });
});

</script>

Original Question Here

我不想改变window.location。我想触发,以便任何绑定到click事件的事件处理程序也将触发。碰巧我也希望浏览器关注链接。

6 个答案:

答案 0 :(得分:2)

当您触发“click”事件时,以及默认行为发生之前,将始终运行您的事件处理程序。所以不,这不是一个错误。

编辑 - 如果您希望在单击元素并满足各种条件时执行默认操作,只需从处理程序中return

$('a').click( function( event )
{
    if ( confirmed == false )
    {
        event.preventDefault();
        confirmed = true;
    }
    else
        return;
});

当您的处理程序返回时,浏览器将继续执行默认行为。

再次编辑 - 当然,如果您只想以编程方式执行带有“href”属性的<a>标记的默认操作,它只是:

   window.location = $(element).attr('href');

根本不需要“点击”活动。

答案 1 :(得分:2)

.trigger('click')不会触发浏览器的默认操作 - 它只会触发绑定到该元素上该事件的jQuery事件处理程序。

查看this answer - 您需要自己创建并触发点击事件。这是答案的代码:

function fireEvent(obj,evt){
    var fireOnThis = obj;
    if( document.createEvent ) {
      var evObj = document.createEvent('MouseEvents');
      evObj.initEvent( evt, true, false );
      fireOnThis.dispatchEvent( evObj );

    } else if( document.createEventObject ) {
      var evObj = document.createEventObject();
      fireOnThis.fireEvent( 'on' + evt, evObj );
    }
}

答案 2 :(得分:0)

preventDefault()不会取消jquery绑定的点击操作;它会取消锚标记固有的“默认”点击操作。 unbind()是用于取消绑定到对象的任何动作/函数的正确函数。

答案 3 :(得分:0)

看起来您有一个状态要阻止默认操作(并更新标志),另一个状态是您只想要应用默认操作。不会完全删除else案例吗?如果没有preventDefault(),默认点击操作仍会运行。

编辑:Pointy的答案现在显示您的代码更新类似。


编辑:我仍然不完全确定你的目的是什么,但如果由于某种原因你必须手动触发,一种防止由于递归引起的堆栈溢出的方法是分配一个自定义事件(即,不是click),然后始终取消默认操作。然后在您的条件中,执行或不执行自定义事件。

所以,像这样(未经测试):

$('a')
  .bind('fancyclick', function () { // Your special click logic
    changeStatusOf( confirmed );
    doCrazyStuff();
    location.replace( $(this).attr('href') ); // or whatever
  })
  .click( function (e) {
    e.preventDefault(); // Always suppress natural click
    if ( confirmed ){
      $(this).trigger('fancyclick'); // Fire the special click
    }
  });

答案 4 :(得分:0)

我只是在分析时编写,希望它易于理解,并且易于与代码进行比较。当我能以任何方式优化/增强我的回复时,请踢我。

检查 - 第1部分

将“preventDefault”移到“if”语句之外!如果你不将它移到“if”之外,如果确认== true,代码将跳过“preventDefault”。

  <script type="text/javascript">
  $( function()
  {
      var confirmed = false;
      $('a').click( function( event )
      {
          event.preventDefault();                  
          if ( confirmed == false )
          {
              confirmed = true;
              $(event.target).trigger( 'click' );
          }
      });
  });
  </script>

检查 - 第2部分

除此之外,我一般都想知道“var确认”的存在。没有它,代码也可以完美无缺,因为你没有在其他地方使用函数中的确认变量......

  <script type="text/javascript">
  $( function()
  {
      $('a').click( function( event )
      {
          event.preventDefault();                  
          $(event.target).trigger( 'click' );
      });
  });
  </script>

检查 - 第3部分

知道你可以通过简单的点击替换触发器,你试过吗?

 <script type="text/javascript">
  $( function()
  {
      $('a').click( function( event )
      {
          event.preventDefault();                  
          $(event.target).click();
      });
  });
  </script>

检查 - 第4部分

如果目标元素上的点击仍然失败,那么如果“event.target”完全拥有一个对象,那么肯定是时候检查(使用“Firefox上的FireBug”等)。你永远不会知道...

检查 - 第5部分

还有一件事:我没有看到任何 Document Ready 检查,所以我希望你把这个脚本放在文件的末尾,就在“&lt; / body&gt;”之前标签。如果您在“&lt; head&gt;”中加载它如果没有检查 Document Ready ,可能会发生javascript尝试将事件绑定到尚未加载到dom中的元素...这就像在9英寸钢板上投掷羽毛一样。 ......什么都不会发生;)

全部

作为对你问题的回答,这就是我想到的一切。其中一个可以解决您遇到的问题。至少,这就是我的希望。 stackoverflow中的这些小片段留下了与我们看不到的相关的大量概率。当你没有“完整视图”时,很难确定可能缺少什么。 ;)

答案 5 :(得分:0)

如何创建一个可以处理最终点击的屏幕外链接?这样,您可以阻止单击原始链接,处理代码,然后继续触发隐藏副本的单击。