в iOS8 использовать.focus () покажет виртуальную клавиатуру и страницу прокрутки после касания

до iOS8, используя Javascript .focus() метод на входном элементе, по-видимому, не будет иметь никакого эффекта (виртуальная клавиатура не будет отображаться). После последней версии iOS 8 запустите .focus() метод, казалось, не влияет на загрузку страницы, но как только пользователь коснулся в любом месте экрана, виртуальная клавиатура мгновенно появится и прокрутит страницу до элемента в фокусе. (Это также проблема, когда я использую атрибут HTML "автофокус")

это изменение вызвало проблемы с пользователями iOS8 на моем сайте. Когда пользователь пытается нажать кнопку на моей странице, внезапная прокрутка и появление клавиатуры заставляют их непреднамеренно нажать кнопку, которая была ниже на экране.

Я предполагаю, что это ошибка в iOS8 и не была преднамеренной функцией, мой вопрос в том, что является наиболее эффективным решением для исправления этой проблемы?

Я должен проверить navigator.userAgent чтобы увидеть, является ли устройство iOS8, каждый раз, когда я использую .focus() способ?

7 ответов


похоже, вы определенно попали в ошибку iOS 8. В iOS7 Safari (по-видимому) игнорирует или сохраняет расфокусированные элементы, которые были установлены до загрузки страницы. Это включает в себя оба <input autofocus> и input.focus() которые происходят до некоторой точки, возможно, загрузка страницы (я тестировал только со встроенным скриптом).

в iOS 8 Safari теперь, по-видимому, помнит, что элемент был сфокусирован, но на самом деле не фокусировал его до события касания. Затем он слепо отправляет событие click в какой бы элемент ни получил прикосновение.

оба браузера ведут себя одинаково для input.focus() происходит после загрузки страницы. Они оба приближаются к элементу и вызывают клавиатуру.

тесты:

хорошая новость заключается в том, что вам нужно беспокоиться только о новом поведении на элементах, которые вы хотите перефокусировать. Другая хорошая новость заключается в том, что, хотя вам придется использовать обходной путь user-agent, вы можете использовать его для всех версий iOS, поскольку они уже ведут себя так, как будто вы не автофокусируете:

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

это, кажется, подход http://www.google.com пользы основанные на некотором основном тестирование агента пользователя:

  • Mac Book Pro: автофокусировка перед загрузкой страницы.
  • iPhone: нет автофокусировки
  • iPad: нет автофокусировки
  • Kit Kat (Android): фокус после загрузка страницы, возможно, дополнительное обнаружение наличия программной клавиатуры.

если у вас нет, вы должны пойти вперед и подать радар с Apple в https://bugreport.apple.com.


Если вы разрабатываете проект Cordova, вы можете исправить это, добавив строку

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

на . Протестировано в IOS 8.3 и IOS 8.4


похоже, что в iOS 8 произошло изменение API для обработки по умолчанию для команды javascript focus (). Если ваше приложение является гибридным приложением, в котором у вас есть прямой контроль над фасадом веб-вида Apple, ниже прямо из документов Apple.

логическое значение, указывающее, может ли веб-содержимое программно покажите клавиатуру.

[myWebView setKeyboardDisplayRequiresUserAction:YES];

когда это свойство установите значение да, пользователь должен явно нажать элементы в веб-представлении для отображения клавиатуры (или другой соответствующей вид ввода) для этого элемента. Если задано значение Нет, событие фокусировки на элемент вызывает отображение входного представления и связывается с ним элемент автоматически.

значение по умолчанию для этого свойства-YES.

из последнего абзаца, кажется, вызов этого метода не является строго для клавиатуры. Это означает, что для входных представлений по всем направлениям, т. е. выпадающего списка и выбора даты и т. д.

кажется, что есть ошибка, поскольку этот вызов метода в настоящее время не работает для меня. Текущее поведение, которое я получаю, соответствует, как будто по умолчанию оно равно NO.


У меня есть решение:

  1. отключить все входы
  2. включить ввод, который вы хотите сфокусировать
  3. установить фокус на этот вход
  4. повторно включить все остальные входы

вот условный monkeypatch для jQuery.focus поэтому вам не нужно добавлять тест userAgent везде.

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)

примечание: Я возвращаюсь arguments[0] поэтому мы не нарушаем цепочку методов, таких как $(el).focus().doSomethingElse()


Я зарегистрировал ошибку об этом в Apple Bug Reporter, и они закрыли его как дубликат, что является признаком того, что они работают над исправлением этого. К сожалению, они не дали мне дополнительной информации о дубликате или о самой проблеме. Я могу видеть только состояние повторяющегося элемента, которое открыто.


для тех, кто приходит к этому на 2018, есть плагин, который это исправить. Просто установите это https://github.com/onderceylan/cordova-plugin-wkwebview-inputfocusfix и input.focus() будет работать автоматически без дополнительной работы.