在焦点上接收两个`focusin`事件

时间:2013-01-19 01:07:21

标签: jquery focusin

我正在做什么

在代码的某些部分,我在focusin个事件上有一个监听器,在另一个部分以编程方式将焦点设置在input上。在Chrome,Safari,Firefox上,事件监听器被调用一次,但在IE(包括IE10)上,它被调用两次。我用jQuery的.on()注册了监听器,并用jQuery的.focus()设置了焦点。请参阅下文,了解显示此行为的示例的完整来源,如果您愿意,可以run that example

问题

  1. 即使不使用jQuery,IE也会触发focusin两次。并且只有在以编程方式设置焦点时才会这样做,而不是在用户选项卡或单击字段时。为什么?它只是一个IE漏洞,还是IE有这么好的理由?
  2. 无论是否是IE错误,jQuery不应该在这里搞清楚IE和其他浏览器之间的区别吗?换句话说,是不是这样做了jQuery bug?
  3. 你会如何解决这个问题? (即所以我可以拥有每个焦点只运行一次的代码,无论是以编程方式还是由用户设置焦点。)
  4. 完整来源

    <!DOCTYPE html>
    <html>
        <head>
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
            <script>
                $(function() {
                    $('input').on('focusin', function() {
                        var c = $('#count');
                        $('#count').text(1 + parseInt(c.text()));
                        console.log('focusin');
                    });
                    $('input').focus();
                });
            </script>
        </head>
        <body>
            <input>
            <code>focusin</code> received: <span id="count">0</span>.
        </body>
    </html>
    

2 个答案:

答案 0 :(得分:3)

这绝对是一个IE问题。来自JQuery 1.9 upgrade guide

  

不幸的是,所有版本的Internet Explorer(6到10)都会触发   异步聚焦事件。当你在IE中使用.trigger(“焦点”)时,jQuery   不会“看到”稍后会发生的异步焦点事件,因此它会触发   它自己的一个,以确保焦点事件始终如所描述的那样发生   以上。这会导致对事件处理程序的两次调用。为了避免这种情况   双重调用 - 但是根本没有调用事件处理程序的风险 - 使用   DOM焦点方法直接,例如$(“selector”)。get(0).focus()。

我使用了$('input').get(0).focus(),并且在加载页面方面不一致。如果我将代码移动到按钮,那么我始终会触发focusin事件。

答案 1 :(得分:1)

我有一个不同的解决方案。它很难看,但很有效。

  1. 创建一个自己的focus_handler()函数并将其绑定到焦点事件
  2. 在调用.focus()之前取消绑定焦点事件 //记得IE会在这里调用两次焦点
  3. 在您再次需要之前将focus_handler绑定到焦点事件(例如:focusout,click)
  4. 这对我有用。