【问题标题】:Changing browser tabs undesirably fires the focus event, especially in Google Chrome更改浏览器选项卡会意外触发焦点事件,尤其是在 Google Chrome 中
【发布时间】:2012-05-18 17:31:39
【问题描述】:

我刚刚发现的焦点事件有点问题。显然,当切换到另一个浏览器选项卡然后再返回时,焦点会触发。我宁愿不发生这种情况;有可能吗?

直到今天我才意识到这一点。这是一个小演示:http://jsfiddle.net/MJ6qb/1/

var times = 0;
$('input').on('focus', function() {
    times ++;
    $(this).after('<br>Focused '+times+' times');   
});

重现:专注于输入,然后切换浏览器选项卡,然后切换回来。当您切换回选项卡时,所有浏览器似乎都会触发焦点事件,并且 Google Chrome 19 会触发两次

理想情况下,切换浏览器选项卡时该功能根本不应该运行,而只能在用户单击或 Tab 时运行,但现在我知道 Chrome 问题我有点担心那是因为它在我的真实应用程序中导致额外的不需要的背靠背 AJAX 请求(它用于获取需要最新的自动完成的结果,但不是我想使用 keyup 事件)。

它似乎与 jQuery 无关(我确实使用 vanilla javascript 进行了测试),但我可以使用 jQuery 作为解决方案。对此我能做些什么吗?我知道我可以使用 jQuery 的 one(),但我确实希望该函数运行不止一次。

【问题讨论】:

  • 有点不相关,但您可能能够检测到浏览器选项卡何时聚焦或模糊,并覆盖this 中的默认行为。据我所知,Chrome 的双火是known bug
  • 啊,谢谢你,没有意识到这是一个已知的错误,只是在发布之前在 Chrome 中测试代码时发现它,以确保它不是 FF 的东西(我在)。我有点想放弃并“让它骑”,但这真的很烦人。我会看看我是否可以用那个答案中的代码做点什么。
  • 您遇到的行为是预期的。当您离开选项卡时,您将取消该文本框的焦点,当您返回时,您将再次关注它。离开另一个应用程序也是如此。不幸的是,我想不出一种方法来覆盖或解决这个问题。
  • 只要模糊事件也触发(似乎是这种情况),我想这是有道理的 - 我只是从未意识到。

标签: javascript jquery google-chrome


【解决方案1】:

试试this

var times = 0;
var prevActiveElement;

    $( window ).on( "blur", function(e){
            prevActiveElement = document.activeElement;
    });

    $('input').on('focus', function() {
        if (document.activeElement === prevActiveElement) {
            return;
        }
        prevActiveElement = document.activeElement;
        times++;
        $(this).after('<br>Focused ' + times + ' times');
    }).on( "blur", function(){
        prevActiveElement = null;  
    });​

【讨论】:

  • 看起来这行得通!感谢您的解决方法!也从来不知道activeElement,非常感谢您提供的那条信息。
  • 顺便说一句,这在生产环境中也能完美运行,具有多个输入:jsfiddle.net/MJ6qb/5(如果您好奇,请打开控制台查看请求)。
  • @WesleyMurch $("body").on("blur") 根本没有被触发。 Blur 不会冒泡,你可能想要$("body").on( "focusout", "[data-autocomplete]", fn)。焦点的等价物是$("body").on( "focusin", "[data-autocomplete]", fn)
  • 啊,感谢您发现这一点,我将模糊事件附加到错误的对象上。
  • 仍然习惯于on 而不是live。好的,通过链接修复.on('focusout', function(){ prevActiveElement = null; }); 太好了,谢谢。
【解决方案2】:

试试这个来解决这个问题:

var times = 0, foc=true;

$(window).on('focus', function() {
    foc = false;
    setTimeout(function() {foc=true}, 200);
});

$('input').on('focus', function() {
    if (foc || times===0) {
        times ++;
        $(this).after('<br>Focused '+times+' times');   
    }
});

FIDDLE

【讨论】:

  • 到目前为止,除非您首先使用 TAB 之类的其他方法(或先单击另一个输入)聚焦,否则点击不会触发 - 仍在测试中。但是,是的,有趣的解决方案!
  • 这很奇怪,在 Chrome 中似乎工作正常,每次都会触发焦点事件,但不会在浏览器选项卡更改时触发。
  • 如果您在执行任何其他操作之前单击输入,它似乎不起作用。 @adeno 你试过了吗?
  • 是的,在 Firefox 中也是如此。为了触发事件,我必须先“聚焦”到窗口中,然后再聚焦到输入字段中。
  • 啊,我明白了,由于某种原因没有尝试过,总是先点击窗口,但无论如何更新了答案,现在应该可以了!
猜你喜欢
  • 1970-01-01
  • 2011-11-15
  • 1970-01-01
  • 2011-02-11
  • 2013-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多