Chrome的Omnibox上按下回车键时触发keyup事件监听器

8
在Chrome浏览器中,当使用以下代码片段时:
  $(document).on('keyup', function(){
    alert("Hey");
  });

每次我在URL栏中按下“enter”键时(例如当我剪切和粘贴页面本身的URL时),事件监听器都会触发。为什么会这样呢?
编辑:这让我感到惊讶,因为URL栏不在document中(可能在window中?)而且Firefox没有这种行为。当我寻找e.target时,Chrome Inspector显示body。我认为这可能是由于事件冒泡引起的,所以我尝试了以下代码:
  $(document).on('keyup', function(e){
    e.stopPropagation();
    alert("Hey");
  });

但它不起作用。 如何防止其被触发?

4个回答

9
这是因为一旦在地址栏中按下回车键,焦点就会转移到页面上。如果您尝试使用onkeydown做相同的操作,地址栏将不会发生任何变化,因为它并不是文档的一部分。过滤地址栏误报事件的一种方法是检查每个keyup是否有相应的keydown键。
<script>
var down = false;
document.addEventListener('keydown', function (){
    down = true;
}, false);

document.addEventListener('keyup', function (){
    if(down === true){
        alert('It was from the page!');
    }
    else{
        alert('Omnibox. Ignore it.');
    }
    down = false;
}, false);

</script>

演示。

制作自己的HTML页面并尝试它,最好这样做,因为PasteHTML.com将其放入iframe中。为了在那里正确地工作,请先单击文本以使iframe获得焦点。

演示。 记住要使用鼠标聚焦于地址栏并输入,而不是使用键盘快捷键。(这会触发onkeydown事件,从而产生错误的结果)

更新:截至Chrome 35,这种情况不再发生。但我不知道他们在哪个版本上修复了它。


2
Chrome的解决方案很简单:使用keypress代替keyup。这种方法并不适用于所有情况(IE),因此您可能需要添加条件以根据浏览器类型切换类型。但是,这将解决您的问题。
请注意,查找特定的按键代码可能会使您的问题无效。祝你好运。

keypresskeyup 不是同一件事情。 - Some Guy
1
@Amaan 不是的。然而,根据提问者打算使用关键事件实现的功能,它们可能是可互换的。 - user677526

1

如果有帮助的话,您可以过滤按键代码... 13 是回车键

$(document).on('keyup', function(event){
  if( parseInt(event.keyCode,10) !== 13 ){
      alert("Hey");
  } 
});​

我需要那个事件来触发页面内的其他有趣事物 ;) - Manuel Bitto

0
一个可能的解决方案是稍微延迟“keyup”事件处理程序的注册。这将跳过在Chrome和Safari中似乎发生的第一个“虚假”触发器。
$(function() {
    setTimeout(
        function() {
            console.log("Delayed event attachment");
            $(document).bind('keyup', log);
        }, 10);
});

function log(e) {
    console.log(e.target.localName);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接