Как я могу предотвратить дикую прокрутку, когда поле формы ввода фиксированной позиции получает фокус?

У меня есть мобильное веб-приложение, которое отображает диалоговое окно в позиции: фиксированный элемент, накладывающий весь экран. Независимо от того, сколько контента отображается или сколько страниц прокручивается, элемент оверлея уменьшает содержимое страницы, и диалог появляется поверх всего. В диалоговом окне есть поле <input type="search /> .

На Android, когда пользователь вводит входное поле, чтобы придать ему фокус, происходит довольно довольно неустойчивое поведение (но не всегда):

  • Появляется мягкая клавиатура, затем сразу исчезает.
  • Основная страница (покрытая наложением) прокручивается на несколько десятков пикселей, иногда вверх, иногда вниз, иногда в обоих направлениях, а иногда и несколько раз. Это также происходит, когда поле ввода теряет фокус.
  • Элемент overlay мгновенно сдвигает несколько пикселей вниз и вправо, показывая основное содержимое вдоль верхнего и левого краев экрана. (Он возвращается на место меньше, чем через секунду).

Это на Android 2.3.4 со встроенным браузером. Это может произойти и на других версиях Android.

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

 <head> <style type="text/css"> #menuoverlay { position: fixed; top: 0; bottom: 0; left: 0; right: 0; z-index: 10; background-color: rgba(0,0,0,.75); text-align: center; } #menu { display: inline-block; margin-top: 1em; border: 3px solid #02b; border-radius: 8px; padding: 1ex; background-color: black; color: silver; } </style> </head> <body> <div id="menuoverlay"> <div id="menu"> ...menu items... ...menu items... <form action=""><input type="search"/></form> </div> </div> <div id="content"> ...lots of stuff... ...lots of stuff... ...lots of stuff... </div> <body> 

Кто-нибудь еще видел это поведение? Вы нашли способ предотвратить это?


Очистка сети привела меня к нескольким сообщениям о подобных проблемах. Вот краткое изложение того, что я прочитал до сих пор:

  • На многих устройствах Android встроенный браузер, по-видимому, не использует поля ввода WebKit так, как можно было бы ожидать. Вместо этого, когда html-определенные поля получат фокус, браузер пытается покрыть их новыми текстовыми виджетами, которые он создает отдельно.
  • Эти повторяющиеся текстовые поля часто игнорируют стили CSS, создавая эффект, когда поля выглядят стилизованными до тех пор, пока они не получат фокус, а затем внезапно вернутся к стилю системы по умолчанию.
  • В браузере Android часто не удается правильно расположить эти повторяющиеся поля. Когда они неуместны, они иногда видны, но в другие времена только перемещают цели фокуса без каких-либо визуальных указаний, которые они переместили.
  • Эти проблемы часто появляются, когда элемент предка поля ввода имеет такие стили, как transform: translate3d() , -webkit-backface-visibility или position: fixed .

Вот некоторые релевантные ссылки:

Android Browser textarea прокручивается повсюду, непригодна для использования

Как я могу создать тег HTML INPUT, чтобы он поддерживал CSS, когда был сфокусирован на Android 2.2+?

Исходный браузер Android 2.2 / 2.3 и фиксированное позиционирование

Solutions Collecting From Web of "Как я могу предотвратить дикую прокрутку, когда поле формы ввода фиксированной позиции получает фокус?"

Мне удалось предотвратить мгновенное смещение наложения, установив outline: none из моего элемента input .

Я получил прокрутку дикой страницы и исчезающую клавиатуру, чтобы успокоиться, установив overflow: hidden в body html при показе диалога, а затем удаляя его снова, скрывая диалог. Это приводит к неприятному побочному эффекту сброса положения прокрутки страницы, поэтому я сохраняю его и восстанавливаю при необходимости, и обертываю все эти хакеры в условных выражениях, поэтому он работает только на Android. (Я надеюсь, что мои пользователи Android не будут слишком отвлекаться, когда они видят, что содержимое страницы изменяется под полупрозрачным наложением, когда диалог открыт.)

Интересно, что мне также удалось предотвратить прокрутку дикой страницы, уловив событие touchstart на моем элементе overlay и вызвав функцию preventDefault (). Это заставляет меня задаться вопросом, было ли все это безумие вызвано последовательностью таких событий:

  • touchstart до корня документа
  • Браузер видит touchstart где размещено дублирующее поле ввода
  • Браузер дает фокус на поле ввода
  • Появляется мягкая клавиатура, позволяющая вводить ввод в поле ввода
  • Видовое окно изменено для размещения мягкой клавиатуры
  • Измененный размер окна просмотра во время сенсорного события выглядит как перетаскивание касания в браузер
  • Ложное перетаскивание заставляет страницу прокручивать и отклонять клавиатуру

Я не в конечном итоге поймал touchstart чтобы решить проблему, потому что это помешало полю ввода получить фокус, а вызов focus() из javascript просто не сработал. Я прочитал, что браузер Android отключает метод focus() для полей ввода, что объясняет это поведение. Возможно, он делает это, потому что он не будет работать с дублирующимися текстовыми виджетами, создаваемыми над полями, определенными html.

В моем случае «позиция: исправлена»; Это не проблема, «vertical-align: center»; Или "-webkit-box-align: center;" Нажмите и закройте мягкую клавиатуру, чтобы использовать «-webkit-box-align: start;» Решил мою проблему.