移动 Safari 自动对焦文本字段

IT技术 javascript focus mobile-safari autofocus
2021-02-09 17:22:39

在 Mobile Safari 中,我无法在设置延迟期后专注于文本字段。我附上了一些展示问题的示例代码。如果单击按钮时触发 .focus(),则一切正常。如果您将焦点挂在回调上,例如 setTimeout 函数,那么它只会在移动 safari 中失败。在所有其他浏览器中,有一个延迟,然后焦点发生。

令人困惑的是,即使在移动 safari 中,也会触发“focusin”事件。这(以及 ~ 类似 ~ SO 中的评论)让我认为这是一个移动 safari 错误。任何指导都将被接受。

我已经在模拟器和 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个回答

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

请记住,在 iOS 上将焦点设置在输入元素上会调出键盘 - 所以所有那些在页面加载时将焦点设置在输入元素上的网页,就像谷歌一样,在 iOS 上使用会非常烦人。我猜苹果决定他们必须采取措施来防止这种情况发生。所以我不同意@DA:这是一个功能而不是一个错误。

对此没有已知的解决方法,因此您必须放弃使用延迟的想法。

2012 年 8 月更新:

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

Matt 您在 2012 年 8 月的更新是否意味着我们可以从 setTimeout 事件触发对输入元素的关注?
2021-03-25 17:22:39
@RonnyHeuschkel 谢谢!我们正在实现一个 PhoneGap 应用程序,我们只是在我们的(void)webViewDidFinishLoad:(UIWebView*)theWebView方法中插入了以下代码theWebView.keyboardDisplayRequiresUserAction = NO; 像魅力一样工作!
2021-03-26 17:22:39
只是想补充一点,整个行为是由于 UIWebView 控件的这个属性造成的:developer.apple.com/library/ios/#documentation/uikit/reference/...在 Safari 中,它在 Homescreen Webapps 中设置为“YES”它是“否”,如果您在自己的应用程序中实现控件,则由您决定。
2021-03-27 17:22:39
2021-03-29 17:22:39
"autofocus" 是一个 HTML5 属性,Safari Mobile、Firefox 3.6 和 IE9 不支持它。(我的理解旧的浏览器不支持...但iOS的?)wufoo.com/html5/attributes/02-autofocus.html 无论是苹果/ Safari浏览器“功能”与否,我宁愿它支持对规范根本不起作用。我正在使用蓝牙扫描仪,任何扫描都需要额外的用户交互才能单击文本字段或将焦点设置到字段的按钮。
2021-04-10 17:22:39

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

如何在键盘事件中抬起键盘?听起来很奇怪,但是当我以这种方式处理键盘事件以聚焦新文本字段时,我看到我的键盘消失了......
2021-03-24 17:22:39

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

对我来说,如果它从主屏幕作为 Web 应用程序运行,则 focus() 可以工作。
2021-03-15 17:22:39
请参阅此页面中的评论stackoverflow.com/questions/6287478/...了解其工作原理
2021-04-09 17:22:39

添加到马特答案。至少在 iOS 5.1 上的 Safari 上,这个问题是固定的。你的FastClick作品,也就是合成一个点击事件不会使焦点失效。然而,这并不能帮助那些希望他们的单一focus()代码在所有 iOS 版本上工作的人,叹息。

我能够通过将 .focus() 附加到事件映射中的两个单独事件来使其工作,但它有点笨拙。

添加 FastClick.js 后,iOS 中会发生这种情况: .focus() 仅在被附加到事件的函数激活时才有效。但是 focus 也是 mobile 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();
    }
});
呸,废话,nvm。它是偶然运行的,因为我添加了其他使该函数运行两次的事件。不过,解决方案就在那里。
2021-04-04 17:22:39