【问题标题】:How to detect if click event has been triggered by 'Enter'?如何检测“Enter”是否触发了点击事件?
【发布时间】:2013-10-08 10:01:25
【问题描述】:
//...
<a href="#" id="foo-link">Foo</a>
<script type="text/javascript">

  $('#foo-link').click(function(e) {
    //...
  }

</script>
//...

在 HTML 页面上使用 jQuery,上面定义的 click 处理程序被执行

  1. 当用户点击它和
  2. 当用户通过 Tab 导航到它并点击 Enter

(至少在 Firefox 中)传递给处理程序的点击事件之间似乎没有区别 - 原始键事件“神奇地”转换为点击事件。

有没有办法区分这两种情况?

详细说明为什么我需要区别对待这两种情况:在我的特定情况下,点击处理程序将焦点设置为文本输入字段。此文本输入字段注册了一个keyup 事件处理程序,它发送一个 AJAX 请求。当用户在链接上按 Enter 后触发点击处理程序时,现在聚焦的文本输入字段接收到 keyup 事件,并且错误地发送了 AJAX 请求。

【问题讨论】:

  • 不确定这是否可行,但在点击处理程序中,您可以使用event.keyCode 来检查是否已使用某个键吗?
  • 那么在你描述的场景下,输入字段还是会是空的?那为什么不检查那个,在那种情况下不发出AJAX请求呢?
  • 不,你无法区分,在这两种情况下,引发的事件都是 MouseEvent。您应该为 enter 键附加另一个侦听器,并在这种情况下阻止另一个侦听器
  • @CBroe 确实我通过检查文本字段是否为空来阻止发送 Ajax 请求。不想在问题中详细介绍,但我们开始吧:文本字段有一个红色边框,表示输入无效。但在这个阶段,用户在某种程度上是“无辜的”。
  • 我认为你能做到的唯一方法是为一个键事件附加另一个监听器,然后,如果它是回车键,防止点击事件触发:jsfiddle.net/8m5js

标签: javascript jquery html dom


【解决方案1】:

有没有办法区分这两种情况?

是的,有(至少在 Chrome 中):

$('#foo-link').click(function(event) {
    if (event.originalEvent.detail === 0) {
        // keyboard "click" event
    } else {
        // mouse "click" event
    }
}

您可以查看原始事件的详细信息属性以获取点击次数。如果点击计数为 0,则您知道“点击”来自键盘。如果点击次数大于0,就知道“点击”来自鼠标。

参考:https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail

【讨论】:

  • 这对我来说似乎是一个很好的解决方案。但是,我们如何在 Firefox 上实现这一点?
  • 得到广泛支持(IE10+)。经过大量试验和错误后,我才得出相同的解决方案。我做了这支笔,可以让你测试,有解释:codepen.io/meduzen/pen/QWjrEWx
  • 说它“被广泛支持”是非常不正确的,尤其是“IE10+”部分。虽然event.detail 属性存在,但对于click 事件,它在ie10 和ie11 中始终设置为0。我最近在工作中遇到了这个问题,并且 caniuse 也说它在 ie10/11 中仅部分支持:caniuse.com/mdn-api_uievent_detail
【解决方案2】:

如果事件详情是=== 0,它是由键盘触发的。

$('#foo-link').click(function(e) {
  // e.detail should be enough in the latest version of jQuery.
  if (e.originalEvent.detail) {
    $(this).val('Fired by mouse.');
  } else {
    $(this).val('Fired by keyboard.');
  }
});
#foo-link {
  width: 120px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="foo-link" type="button" value="Press me." />

【讨论】:

    【解决方案3】:

    一种解决方案是处理“鼠标上移”而不是点击:

    <a href="javascript:;" id="foo-link">Foo</a>
    <script type="text/javascript">
    
          $('#foo-link').mouseup(function (e) {
                  alert("Mouse click");
          });
    
    </script>
    

    另一种解决方案是同时处理“点击”和“按键”,如果按下“回车”则返回 false:

    <a href="javascript:;" id="foo-link">Foo</a>
    <script type="text/javascript">
    
        $('#foo-link').click(function (e) {
            alert("Mouse click");
        });
    
        $('#foo-link').keypress(function (e) {
            if (e.which == 13)
                return false;
        });
    
    </script>
    

    【讨论】:

    • @Second 解决方案:在 keypress 事件上返回 false 不会阻止 单独 keyup 事件的发生,对吗?
    • 否,但它会阻止 click 事件的发生。
    • 只有当 OP 同意他想禁止输入时的点击事件时。一般来说,可访问性是一个很大的问题。
    • 是的,这就是我展示两个解决方案的原因,所以你可以选择使用什么:)
    【解决方案4】:

    处理这个问题的方法可能有点长,但确实有效: http://jsbin.com/azATuHe/3(查看console.log)

     $('.txtB').on('keyup', function(e){ 
        if ( $('#anSetF').data('enterpressed' ) == true ) {
          console.log ( 'keyup triggered on TEXTBOX but suppressed' );
          $('#anSetF').data('enterpressed', false )
          return true;
      }else{
        console.log ( 'keyup triggered on TEXTBOX Fire AJAX now : ' +  $('#anSetF').data('enterpressed' ) );
        //Existing code to fire AJAX
      }
    
    
      });
    
    $('#anSetF').on('keydown.Enter', function(e){
        console.log('KEY UP: ' + e.which );
        if ( e.which == 13 ){
           $(this).data('enterpressed',true);
        }
      }).on('click', function(){
          //Some code which you used to focus the textbox
          $('.txtB').focus();
      });
    

    【讨论】:

      【解决方案5】:

      你可以只检查鼠标坐标的存在:

      function handleClick(event) {
        if (!event.originalEvent.clientX && !event.originalEvent.clientY) {
          // Enter key pressed
        }
      }
      

      唯一不起作用的情况是当点击页面左上角的最像素时。在大多数情况下,这应该不是问题。

      【讨论】:

        【解决方案6】:

        我的脚本有类似的东西。但我最终使用.keyup 而不是点击。它允许我检查单击了哪个按钮。

                $("#searching").keyup(function () {
                if (window.event.keyCode == 38 || window.event.keyCode == 40 || window.event.keyCode == 32) {
                    return false;
                }
                var mystring = document.getElementById('searching').value;
                if (timeoutReference) clearTimeout(timeoutReference);
                if (!mystring.match(/\S/)) {
        
                    $.ajax({
                            //Rest of code here..
        

        【讨论】:

          【解决方案7】:

          这应该可以工作

          $('#foo-link').keyup(function(e) {
                  if(e.which == 13)
                      console.log('Enter is pressed');
          });
          

          【讨论】:

          • 用鼠标点击怎么样??也需要处理
          【解决方案8】:

          为您的链接制作outline:0。现在,用户无法通过标签查看链接上的大纲。所以,他不知道他在哪个按钮上,所以他不会点击回车键,但focus 会出现在元素上,如果他按下回车,做你的事,否则做你的事。即使不设置outline:0,代码仍然可以工作,因为焦点在它上面。

          【讨论】:

            猜你喜欢
            • 2013-02-23
            • 2016-10-22
            • 1970-01-01
            • 2014-06-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-04-28
            相关资源
            最近更新 更多