Intereting Posts

Android не корректно прокручивает фокус ввода, если не элемент тела

Когда мобильный браузер вызывает клавиатуру, он пытается переместить полосы прокрутки таким образом, чтобы вход все еще находился в поле зрения.

На iOS Safari, похоже, это делается правильно, если найти ближайшего родителя прокрутки.

В Android-браузере или на мобильном браузере Chrome он просто попробовал элемент body, а затем сдался, поэтому сфокусированный вход скрыт под клавиатурой.

Как сломать

Установите overflow-y: hidden на элементе body. Создайте прокручиваемый контейнер и поместите туда форму.

Когда вы выбираете элемент в нижней части экрана, он будет скрыт от клавиатуры.

демонстрация

http://dominictobias.com/android-scroll-bug/

 <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"/> <title>Android scroll/focus bug</title> <style> html, body { margin: 0; padding: 0; height: 100%; overflow: hidden; } .scroll { position: absolute; top: 0; right: 0; bottom: 0; left: 0; overflow-y: scroll; } input { margin-bottom: 20px; width: 100%; } </style> </head> <body> <div class="scroll"> <input type="text" value="Input 1"> <input type="text" value="Input 2"> <input type="text" value="Input 3"> <input type="text" value="Input 4"> <input type="text" value="Input 5"> <input type="text" value="Input 6"> <input type="text" value="Input 7"> <input type="text" value="Input 8"> <input type="text" value="Input 9"> <input type="text" value="Input 10"> <input type="text" value="Input 11"> <input type="text" value="Input 12"> <input type="text" value="Input 13"> <input type="text" value="Input 14"> <input type="text" value="Input 15"> <input type="text" value="Input 16"> <input type="text" value="Input 17"> <input type="text" value="Input 18"> <input type="text" value="Input 19"> <input type="text" value="Input 20"> </div> </body> </html> 

Любые идеи, как это исправить? Будет ли это требовать обнаружения браузера и грязных хаков?

Solutions Collecting From Web of "Android не корректно прокручивает фокус ввода, если не элемент тела"

Это ошибка в исходном браузере Android. Кстати, вход прокручивается в представление после ввода символа на мягкой клавиатуре.

Следующий фрагмент кода, размещенный где-то на странице, должен помочь:

 if(/Android 4\.[0-3]/.test(navigator.appVersion)){ window.addEventListener("resize", function(){ if(document.activeElement.tagName=="INPUT"){ window.setTimeout(function(){ document.activeElement.scrollIntoViewIfNeeded(); },0); } }) } 

Ответ от Сержа велик, но у меня было несколько модификаций, которые улучшили его для меня.

Проблема появилась и на Android 6, поэтому я добавил ее в чек, и мне нужно было исправить работу как для текстовых полей, так и для ввода.

 if(/Android [4-6]/.test(navigator.appVersion)) { window.addEventListener("resize", function() { if(document.activeElement.tagName=="INPUT" || document.activeElement.tagName=="TEXTAREA") { window.setTimeout(function() { document.activeElement.scrollIntoViewIfNeeded(); },0); } }) } 

Если кто-то нуждается в исправлении в Angular 1, вот что я использовал там.

 angular.module('<module name>').run(function ($window, $timeout) { if(/Android [4-6]/.test($window.navigator.appVersion)){ $window.addEventListener("resize", function(){ if(document.activeElement.tagName=="INPUT" || document.activeElement.tagName=="TEXTAREA"){ $timeout(function() { document.activeElement.scrollIntoViewIfNeeded(); }); } }); } }); 

Предлагая небольшую ревизию, если она кого-то экономит:

  • Не нужно указывать версию Android # (менее вероятно, чтобы сломаться, когда ваш пользователь получит Android 7.0+)
  • Не нужно обертывать setTimeOut
  • MDN советует против .scrollIntoViewIfNeeded bc несовместимости браузера => .scrollIntoView – это выполнимая замена с немного большей совместимостью с браузером

     if(/Android/.test(navigator.appVersion)) { window.addEventListener("resize", function() { if(document.activeElement.tagName=="INPUT" || document.activeElement.tagName=="TEXTAREA") { document.activeElement.scrollIntoView(); } }) } 

Если посмотреть на это несколько иначе, ошибка, как представляется, вызвана функцией «Предложения» браузера. Поскольку я вообще не хочу предложений, я использовал:

 if(/Android/.test(navigator.appVersion)){ $('input[type="text"]').attr('autocomplete', "off"); } 

Что дает гораздо более плавный опыт.