【问题标题】:Mobile Safari Autofocus text field移动 Safari 自动对焦文本字段
【发布时间】:2011-09-11 08:42:26
【问题描述】:

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

令人困惑的是,“focusin”事件被触发了,即使在移动 safari 中也是如此。这(和 SO 中的 ~ 相似 ~ cmets)让我认为这是一个移动 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>

~类似~ SO问题:

【问题讨论】:

  • Mobile Safari 有一些焦点问题。例如,您不能通过正文的 onload 事件将焦点应用于字段。我猜这也是一个错误。
  • @DA 我也开始认为这确实存在于 Mobile Safari 中浮动的 focus() 问题。

标签: javascript focus mobile-safari autofocus


【解决方案1】:

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

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

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

2012 年 8 月更新:

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

【讨论】:

  • "autofocus" 是 HTML5 属性,Safari Mobile、Firefox 3.6 和 IE9 不支持它。 (我了解较旧的浏览器不支持它......但 iOS?)wufoo.com/html5/attributes/02-autofocus.html 无论它是否是 Apple/Safari 的“功能”,我都希望它支持规范而不是完全不支持。我正在使用蓝牙扫描仪,任何扫描都需要额外的用户交互才能单击文本字段或将焦点设置到字段的按钮。
  • Matt 您在 2012 年 8 月的更新是否意味着我们可以从 setTimeout 事件触发对输入元素的关注?
  • 只是想补充一下,整个行为是由于 UIWebView 控件的这个属性:developer.apple.com/library/ios/#documentation/uikit/reference/… 在 Safari 中它设置为“是”,在主屏幕 Web 应用程序中它是“否”,如果您可以在自己的应用中实现控件,这取决于您。
  • @RonnyHeuschkel 谢谢!我们正在实现一个 PhoneGap 应用程序,我们刚刚在 (void)webViewDidFinishLoad:(UIWebView*)theWebView 方法中插入了以下代码:theWebView.keyboardDisplayRequiresUserAction = NO; 就像一个魅力!
【解决方案2】:

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

【讨论】:

  • 如何在键盘事件中抬起键盘?听起来很奇怪,但是当我处理键盘事件以使新的文本字段成为焦点时,我看到我的键盘消失了......
【解决方案3】:

focus() 似乎只有在您已将站点添加到主屏幕并使用此链接打开站点时才有效。

【讨论】:

【解决方案4】:

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

【讨论】:

    【解决方案5】:

    我能够通过将 .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();
        }
    });
    

    【讨论】:

    • 呸,废话,nvm。它意外地起作用,因为我添加了其他使函数运行两次的事件。解决方案就在附近。
    【解决方案6】:

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

    $("#searchField").trigger("focus");

    【讨论】:

    • 根据 jquery 文档, .focus() 别名为 .trigger("focus") 。
    猜你喜欢
    • 2015-11-14
    • 1970-01-01
    • 2016-01-03
    • 2021-07-11
    • 2015-07-30
    • 2019-02-12
    • 2011-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多