5

我在做什么

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

问题

  1. 即使不使用 jQuery,IE 也会触发focusin两次。只有在以编程方式设置焦点时才会这样做,而不是在用户选项卡或单击字段时。为什么?它只是一个 IE 错误,还是 IE 有充分的理由这样做?
  2. 不管是不是 IE 的 bug,jQuery 不应该在这里解决 IE 和其他浏览器的区别吗?换句话说,这样做是不是一个 jQuery 错误?
  3. 你将如何解决这个问题?(也就是说,我可以让每个焦点只运行一次的代码,无论焦点是通过编程方式设置还是由用户设置。)

完整来源

<!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>
4

2 回答 2

3

这绝对是一个IE问题。从JQuery 1.9 升级指南

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

我用过$('input').get(0).focus(),它在页面加载上不是很一致。如果我将代码移动到一个按钮,那么我会始终focusin触发事件。

于 2013-01-19T02:33:13.657 回答
1

我对此有不同的解决方案。这很丑陋,但有效。

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

这对我有用。

于 2013-11-12T16:22:23.717 回答