Javascript 在 iOS8 中使用 .focus() 将在触摸后显示虚拟键盘和滚动页面

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26146252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 22:24:13  来源:igfitidea点击:

in iOS8 using .focus() will show virtual keyboard and scroll page after touch

javascriptiosuikeyboardautofocus

提问by Mac Mad Ill

Prior to iOS8, using the Javascript .focus()method on an input element would appear to have no effect (the virtual keyboard would not display). After the latest iOS 8 release, running the .focus()method seemed to have no effect on page load but once a user touched anywhere on the screen the virtual keyboard would instantly appear and scroll the page to the element in focus. (This is also an issue when I use the HTML attribute "autofocus")

在 iOS8 之前,.focus()在输入元素上使用 Javascript方法似乎没有效果(虚拟键盘不会显示)。在最新的 iOS 8 版本之后,运行该.focus()方法似乎对页面加载没有影响,但是一旦用户触摸屏幕上的任何位置,虚拟键盘就会立即出现并将页面滚动到焦点元素。(当我使用 HTML 属性“autofocus”时,这也是一个问题)

This change has caused issues with iOS8 users on my site. When a user attempts to click a button on my page the sudden scroll and keyboard appearance causes them to unintentionally click a button that was lower on the screen.

此更改导致我网站上的 iOS8 用户出现问题。当用户尝试单击我页面上的按钮时,突然的滚动和键盘外观会导致他们无意中单击屏幕下方的按钮。

I am assuming this is a bug in iOS8 and was not intentional feature, my question is what is the most efficient solution to fixing this problem?

我假设这是 iOS8 中的一个错误并且不是故意的功能,我的问题是解决这个问题的最有效的解决方案是什么?

Do I have to check navigator.userAgentto see if the device is iOS8, every time I use the .focus()method?

navigator.userAgent每次使用该.focus()方法时是否都必须检查设备是否为iOS8 ?

采纳答案by Brian Nickel

It looks like you're definitely hitting an iOS 8 bug. In iOS7, Safari would (apparently) ignore or keep unfocused elements that had focus set prior to page load. This includes both <input autofocus>and input.focus()that occur up to some point, possibly page load (I tested just with an inline script).

看起来您肯定遇到了 iOS 8 错误。在 iOS7 中,Safari 会(显然)忽略或保留在页面加载之前设置焦点的未聚焦元素。这包括<input autofocus>input.focus()发生在某个时间点,可能是页面加载(我仅使用内联脚本进行了测试)。

In iOS 8, Safari is now apparently remembering that the element was focussed but not actually focussing it until a touch down event. It is then blindly sending a click event to whichever element received the touch up.

在 iOS 8 中,Safari 现在显然记住了元素被聚焦,但直到触地事件才真正聚焦它。然后它会盲目地向收到修饰的任何元素发送点击事件。

Both browsers behave the same for input.focus()occurring after page load. They both zoom to the element and bring up the keyboard.

两种浏览器input.focus()在页面加载后的行为相同。它们都缩放到元素并调出键盘。

Tests:

测试:

The good news is that you only need to be worried about new behavior on elements you want to prefocus. The other good news is that while you will have to use a user-agent workaround, you can use it for all iOS versions since they were already behaving like you weren't autofocusing:

好消息是你只需要担心你想要预先聚焦的元素的新行为。另一个好消息是,虽然您必须使用用户代理解决方法,但您可以将其用于所有 iOS 版本,因为它们已经表现得好像您没有自动对焦:

if (!/iPad|iPhone|iPod/g.test(navigator.userAgent)) {
    element.focus();
}

This appears to be the approach http://www.google.comuses based on some basic user-agent testing:

这似乎是http://www.google.com基于一些基本用户代理测试使用的方法:

  • Mac Book Pro: autofocus before page load.
  • iPhone: no autofocus
  • iPad: no autofocus
  • Kit Kat (Android): focus afterpage load, possibly doing extra detection for presence of software keyboard.
  • Mac Book Pro:页面加载前自动对焦。
  • iPhone:没有自动对焦
  • iPad:没有自动对焦
  • Kit Kat (Android):页面加载聚焦,可能对软件键盘的存在进行额外检测。

If you haven't, you should go ahead and file a radar with Apple at https://bugreport.apple.com.

如果你还没有,你应该继续在https://bugreport.apple.com 上向 Apple 提交一份雷达报告。

回答by Del

If you are developing a Cordova project, you can fix it adding this line

如果你正在开发一个 Cordova 项目,你可以通过添加这一行来修复它

<preference name="KeyboardDisplayRequiresUserAction" value="false" />

to your config.xmlfile. Tested in IOS 8.3 and IOS 8.4

到您的config.xml文件。在 IOS 8.3 和 IOS 8.4 中测试

回答by xMythicx

It seems that in iOS 8 there has been an API change on the default handling for the javascript focus() command. If your application is a hybrid app in which you have direct control over Apple's web view facade the below is directly from apples docs.

似乎在 iOS 8 中对 javascript focus() 命令的默认处理进行了 API 更改。如果您的应用程序是一个混合应用程序,您可以在其中直接控制 Apple 的 Web 视图外观,则以下内容直接来自 Apples 文档。

A Boolean value indicating whether web content can programmatically display the keyboard.

[myWebView setKeyboardDisplayRequiresUserAction:YES];

When this property is set to YES, the user must explicitly tap the elements in the web view to display the keyboard (or other relevant input view)for that element. When set to NO, a focus event on an element causes the input view to be displayed and associated with that element automatically.

The default value for this property is YES.

一个布尔值,指示 Web 内容是否可以以编程方式显示键盘。

[myWebView setKeyboardDisplayRequiresUserAction:YES];

当此属性设置为 YES 时,用户必须明确点击 Web 视图中的元素以显示该元素的键盘(或其他相关输入视图)。当设置为 NO 时,元素上的焦点事件会导致输入视图自动显示并与该元素关联。

此属性的默认值为 YES。

From the last paragraph it seems this method call is not strictly for the keyboard. It indicates that it is for input views across the board i.e. drop down and date picker etc.

从最后一段来看,这个方法调用似乎并不严格适用于键盘。它表示它用于全面的输入视图,即下拉和日期选择器等。

It seems though there is a bug as this method call is not currently working for me. The current behavior I am receiving corresponds as if it defaults to NO.

似乎有一个错误,因为此方法调用目前对我不起作用。我收到的当前行为相当于默认为 NO。

回答by Diodeus - James MacFarlane

I have a solution:

我有一个解决方案:

  1. Disable all inputs
  2. Enable the input you wish to focus
  3. Set the focus to that input
  4. Re-enable all the other inputs
  1. 禁用所有输入
  2. 启用您希望关注的输入
  3. 将焦点设置为该输入
  4. 重新启用所有其他输入

回答by Adam Fraser

Here's a conditional monkeypatch for jQuery.focusso you don't need to add the userAgent test everywhere.

这是一个有条件的monkeypatch,jQuery.focus因此您无需在任何地方添加 userAgent 测试。

JavaScript

JavaScript

if (/iPad|iPhone|iPod/g.test(navigator.userAgent)) {
  (function($) {
    return $.fn.focus = function() {
      return arguments[0];
    };
  })(jQuery);
}

CoffeeScript

咖啡脚本

if /iPad|iPhone|iPod/g.test navigator.userAgent
  (($) ->
    $.fn.focus = ->
      arguments[0]
  )(jQuery)

Note: I'm returning arguments[0]so we don't break method chaining such as $(el).focus().doSomethingElse()

注意:我回来了,arguments[0]所以我们不会破坏方法链,比如$(el).focus().doSomethingElse()

回答by Ahmad Alfy

For anyone coming to this on 2018, there is a plugin that fix it. Just install this https://github.com/onderceylan/cordova-plugin-wkwebview-inputfocusfixand input.focus()will work automatically without any additional work.

对于 2018 年来到这里的任何人,有一个插件可以修复它。只要安装此https://github.com/onderceylan/cordova-plugin-wkwebview-inputfocusfixinput.focus()会自动工作,无需任何额外的工作。

回答by Lipata

I've logged a bug about this into the Apple Bug Reporter and they closed it as duplicate, which is a sign they are working on fixing this. Unfortunately they didn't give me some more information about the duplicate item or about the problem itself. I can only see the duplicate item state, which is Open.

我已经在 Apple Bug Reporter 中记录了一个关于此的错误,他们将其关闭为重复项,这表明他们正在努力解决此问题。不幸的是,他们没有向我提供有关重复项或问题本身的更多信息。我只能看到重复的项目状态,即打开。