移动Safari自动对焦文本字段

时间:2011-06-09 02:33:26

标签: javascript focus mobile-safari autofocus

在Mobile Safari中,设置延迟时间后,我无法关注文本字段。我附上一些展示问题的示例代码。 如果单击该按钮,则触发.focus(),一切都按预期工作。如果你把焦点放在回调上,比如setTimeout函数,那么它只能在移动safari中失败。在所有其他浏览器中,有一个延迟,然后焦点发生。

令人困惑的是,即使在移动游猎中,也会触发“focusin”事件。这个(和SO中的〜类似〜评论)让我觉得它是一个移动的safari bug。任何指导都将被接受。

我已经在模拟器和iPhone 3GS / 4 iOS4上进行了测试。

示例HTML:

<!DOCTYPE html> 
  <html lang='en'> 
    <head> 
      <title>Autofocus tests</title> 
      <meta content='width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0' name='viewport'> 
      <meta content='yes' name='apple-mobile-web-app-capable'> 
    </head> 
    <body>
      <h1> 
        Show keyboard without user focus and select text:
      </h1> 
      <p> 
        <button id='focus-test-button'> 
          Should focus on input when you click me after .5 second
        </button> 
        <input id='focus-test-input' type='number' value='20'> 
      </p> 
      <script type="text/javascript"> 
        //<![CDATA[
        var button = document.getElementById('focus-test-button');
        var input  = document.getElementById('focus-test-input');

        input.addEventListener('focusin', function(event) {
          console.log('focus');
          console.log(event);
        });

        button.addEventListener('click', function() {
          // *** If triggered immediately - functionality occurs as expected
          // input.focus();
          // *** If called by callback - triggers the focusin event, but does not bring up keyboard or cursor
          var t = setTimeout("input.focus();",500);
        });
        //]]>
      </script>
    </body>
  </html>

〜相似〜问题:

6 个答案:

答案 0 :(得分:80)

我认为这是移动Safari的一个功能,而不是一个bug。在FastClick的工作中,我和我的同事们发现,如果调用堆栈中的第一个函数是由非程序化事件触发的,iOS将只允许在函数内的其他元素上触发焦点。在您的情况下,对setTimeout的调用会启动一个新的调用堆栈,安全机制会启动以防止您将注意力设置在输入上。

请记住,在iOS设置上,关注输入元素会调出键盘 - 因此所有那些专注于页面加载的输入元素的网页,就像Google一样,在iOS上使用会非常烦人。我猜Apple决定他们必须采取措施来防止这种情况发生。所以我不同意@DA:这是一个不是bug的功能。

对此没有已知的解决方法,所以你不得不放弃使用延迟的想法。

2012年8月更新:

从iOS 5开始,允许由合成点击事件触发的处理程序触发对输入元素的关注。请尝试更新的FastClick input focus example

答案 1 :(得分:5)

只有当原始事件来自用户交互而不是来自setTimeout时,我才能通过调度点击事件来提升键盘。我相信结果是你可以从touchend事件中提升键盘,但仍然不会超时。

答案 2 :(得分:1)

如果您已将网站添加到主屏幕并使用此链接打开网站,则focus()似乎只有效。

答案 3 :(得分:0)

添加到Matt的答案。至少在iOS 5.1上的Safari上,此问题已修复。您的FastClick有效,即合成点击事件不会失败焦点。但是,这对于希望单个focus()代码可以在所有iOS版本上工作的人来说无济于事。

答案 4 :(得分:0)

我能够通过将它附加到事件地图中的两个独立事件来使.focus()工作,但它有点像hacky。

添加FastClick.js之后,iOS就会发生这种情况:.focus()仅在附加到事件的函数激活时才有效。但是焦点也是移动safari的事件映射中的事件,当您使用jQuery的.focus()时,它实际上被调用。所以你可以多余并在对象的焦点事件上附加另一个.focus()以确保它被拉过。当您在DOM中创建输入时,这尤其有用。我最近喜欢为MeteorJS编程,这就是解决方案的样子:

Template.templateName.events({
    "click button":function(){
        Session.set("makeButtonVisible",true);
        $("input.created").focus();
    },
    "focus input.created":function(){
        $("input.created").focus();
    }
});

希望这对那里的人有用,花了我两个小时的时间来计算这个。

修改 好吧,特别是对于MeteorJS,你不能使用Template.templateName.rendered函数,因为必须从事件中调用.focus()。但由于某种原因,当您通过jQuery添加输入时,您可以在事件内部关注它。猜猜这是要走的路。这就是我最终做的事情:

Template.templateName.events({
    "click button":function(){
        $("body").append("<input class='created' type='tel'>");
        $("input.created").focus();
    }
});

答案 5 :(得分:-5)

你自己回答了。如果使用Jquery,则只需触发即可。在触发器上改变焦点()(“焦点”);在你的代码的任何部分。

$( “#searchField”)触发器( “焦点”);