Недавно я работал над проектом чата H5 и столкнулся с одной из самых больших ловушек: поле ввода получает фокус, всплывает программная клавиатура, и поле ввода должно быть адсорбировано (или сверху) при методе ввода. коробка. Требования очень ясны и кажутся простыми, но на самом деле это не так. Поэкспериментировав с некоторыми моделями, мы обнаружили, что в основном возникают следующие проблемы:
Давайте рассмотрим решения вышеупомянутых проблем одно за другим.
Получите всплывающее окно и статус втягивания виртуальной клавиатуры.Важно знать, находится ли программная клавиатура вверху или внизу, и на этом должна основываться последующая обработка совместимости. Однако H5 не отслеживает напрямую события программной клавиатуры. Он может лишь косвенно отслеживать производительность других аспектов страницы, открывая или убирая программную клавиатуру, сохраняя страну. Более того, производительность на IOS и Android разная.
Всплывающее окно с программной клавиатурой iOSВ iOS, когда поле ввода (ввод, текстовая область или форматированный текст) получает фокус, клавиатура всплывает, страница (веб-просмотр) не сжимается или высота (высота) не меняется, но страница (веб-просмотр) как целое прокручивается вверх, а максимальная высота прокрутки (scrollTop) — это высота мягкой клавиатуры.
Всплывающее окно с программной клавиатурой AndroidАналогично, в Android поле ввода получает фокус и появляется клавиатура, но высота страницы (веб-просмотр) изменяется. Вообще говоря, высота — это высота визуальной области (исходная высота минус высота виртуальной клавиатуры). ), за исключением того, что содержимое страницы при расширении может производить прокрутку, но само веб-представление не может прокручиваться.
Производительность свертывания мягкой клавиатуры iOSПри нажатии кнопки отвода на программной клавиатуре или области страницы за пределами поля ввода поле ввода теряет фокус, а программная клавиатура убирается.
Производительность свертывания программной клавиатуры AndroidПри срабатывании области за пределами поля ввода поле ввода теряет фокус, а программная клавиатура убирается. Однако при нажатии кнопки втягивания на клавиатуре поле ввода не потеряет фокус, и программная клавиатура также будет убрана.
Следите за всплывающим окном и сворачиванием программной клавиатуры.Основываясь на вышеупомянутых различных характеристиках всплывающего и сворачивания клавиатуры на IOS и Android, мы можем выполнить следующую обработку отдельно, чтобы отслеживать всплывающее окно и сворачивание программной клавиатуры:
// Оцениваем тип устройства varudgeDeviceType = function () { var ua = window.navigator.userAgent.toLocaleLowerCase(); var isIOS = /iphone|ipad|ipod/.test(ua); var isAndroid = /android/.test ( ua); return { isIOS: isIOS, isAndroid: isAndroid }}()// Слушаем функцию всплывающего окна и свертывания программной клавиатуры в поле ввода. ListenKeybord($input) { if (judgeDeviceType.isIOS) { // Всплывает клавиатура IOS: поля ввода IOS и Android получают фокус, и появляется клавиатура $input.addEventListener('focus', function () { console.log(' Клавиатура IOS Всплывает! '); // Операция после появления клавиатуры IOS}, false) // Клавиатура IOS убирается: IOS Если вы щелкнете за пределами поля ввода или нажмете кнопку «отвести», поле ввода потеряет фокус и клавиатура уберется. $input.addEventListener('blur', () => { console.log('Клавиатура IOS убрана!') ; // Операция после того, как клавиатура IOS сложена }) } // Клавиатура Android сложена: Когда клавиатура Android выдвигается или складывается, высота страницы изменится, и в зависимости от этого клавиатура складывается if (judgeDeviceType.isAndroid) { var originHeight = document.documentElement.clientHeight || document.body.clientHeight; window.addEventListener('resize', function () { var resizeHeight = document.documentElement.clientHeight || document.body.clientHeight; if (originHeight < resizeHeight) { console.log('Клавиатура Android убрана!'); // Действия после того, как клавиатура Android убрана} else { console.log('Появляется клавиатура Android! '); // Операция после появления клавиатуры Android} originHeight = resizeHeight; }, false) }}var $inputs = document.querySelectorAll('.input');for (var i = 0; i < $inputs.length; я++) { ListenKeybord($inputs[i]);} При открытии виртуальной клавиатуры поле ввода всегда прокручивается до видимой области.Иногда мы создаем форму ввода со многими элементами ввода. Поле ввода получает фокус, и появляется программная клавиатура. Когда поле ввода расположено в нижней части страницы, в IOS все веб-просмотр будет свернуто на определенное расстояние, так что сфокусированное поле ввода автоматически окажется в видимой области. Однако на Android этого не произойдет. . Это изменит только высоту страницы без прокрутки к текущему элементу в видимой области.
Поскольку вышеописанное было реализовано для отслеживания всплывающих и убирающихся клавиатур IOS и Android, здесь вам нужно только прокрутить (scrollIntoView()) элемент фокуса в визуальную область после появления клавиатуры Android. Чтобы увидеть эффект, вы можете нажать здесь.
// Получаем элемент фокуса и прокручиваем его до видимой области function activeElementScrollIntoView(activeElement, Delay) { var editable = activeElement.getAttribute('contenteditable') // Поле ввода, текстовая область или форматированный текст не прокручиваются до видимой области после получения область фокуса if (activeElement.tagName == 'INPUT' || activeElement.tagName == 'TEXTAREA' || редактируемый === '' || редактируемый) { setTimeout(function () { activeElement.scrollIntoView(); }, Delay) }}// ...// Работаем activeElementScrollIntoView($input, 1000);// ... после появления клавиатуры Android Создайте чистую цифровую программную клавиатуруВ приведенном выше поле ввода формы требуется ввести номер телефона. Аналогично этому, появится цифровая программная клавиатура. Поскольку мы говорим о совместимости программной клавиатуры, давайте вставим ее сюда. Лучшее решение заключается в следующем:
<p>Пожалуйста, введите номер вашего мобильного телефона</p><input type=tel novalidate=novalidate Pattern=[0-9]* class=input>
Если вы используете версию браузера WeChat для iOS12 и V6.7.4+, чтобы открыть приведенную выше демонстрацию ввода формы, вы будете удивлены, обнаружив, что после убирания клавиатуры страница, которая изначально была прокручена вверх, не возвращается в нижнее положение, вызывая исходная клавиатура для подпрыгивания. Начальная позиция пуста.
Фактически, это ошибка Apple в iOS, и она появится на всех устройствах iOS12, оснащенных Xcode10. WeChat официально предоставил решение. Просто прокрутите страницу (веб-просмотр) обратно в нижнюю позицию окна (позиция clientHeight) после закрытия программной клавиатуры. Восстановленную демо-версию ввода формы, указанную выше, можно нажать здесь.
console.log('Клавиатура IOS убрана!'); // Браузер WeChat версии 6.7.4+IOS12 покажет, что после того, как клавиатура убрана, представление перемещается вверх, но не вниз var wechatInfo = window.navigator.userAgent .match( /MicroMessenger//([/d/.]+)/i);if (!wechatInfo) return;var wechatVersion = wechatInfo[1];var version = (navigator.appVersion).match(/OS (/d+)_(/d+)_?(/d+)?/);if (+wechatVersion.replace(//./g, '') >= 674 && +version[1] >= 12) { window.scrollTo(0, Math.max(document.body.clientHeight, document.documentElement.clientHeight));} Совместимость со сторонними методами ввода.Сказав так много выше, фактически, более половины ошибок поля ввода чата H5 устранены. Теперь давайте посмотрим на базовую структуру HTML поля ввода чата.
<div class=chat__content> <div> <p>Некоторый контент чата 1</p> </div> <!--Опустить тысячи строк содержимого чата--></div><div class=input__content> <div class =input contenteditable=true></div> <button>Отправить</button></div>
стиль
/* Опустить некоторые стили */.chat__content { height:calc(100% - 40px); позиция: абсолютное; слева: 0; справа: 0; внизу: 0; выравнивание элементов: по центру;}/* Опустить некоторые стили*/Это очень просто, просто разделите область содержимого и область ввода. Область ввода абсолютно позиционирована. Согласно приведенному выше демонстрационному методу ввода формы, это правда, что большинство браузеров Android работают нормально, но тест проводился на IOS Browser. собственный метод ввода и для сторонних методов ввода (таких как метод ввода Sogou) поле ввода будет полностью заблокировано для браузера QQ или браузера WeChat, при использовании стороннего метода ввода поле ввода будет заблокировано наполовину; в браузере Baidu, при использовании стороннего метода ввода поле ввода будет заблокировано. Оно также будет полностью закрыто. Чтобы просмотреть эффект, вы можете зайти сюда в соответствующем браузере.
В браузере UC после появления программной клавиатуры высота строки заголовка над браузером имеет динамический эффект задержки уменьшения высоты, что приводит к тому, что веб-просмотр немного прокручивается вниз, а нижнее поле ввода прокручивается до нерабочей области. видимая область.
Что касается стороннего метода ввода, предполагается, что начальное позиционирование прокрутки веб-просмотра неверно из-за неправильного расчета высоты после появления панели метода ввода. Фактически, эти две точки вызваны тем, что веб-просмотр не прокручивается на месте. После появления виртуальной клавиатуры элемент фокуса можно снова прокрутить до видимой области, заставив веб-просмотр переместиться на место.
console.log('Всплывает клавиатура Android!');activeElementScrollIntoView($input, 1000); Решение для взлома, совместимое с браузером Android XiaomiВ браузере Xiaomi на Android после применения описанного выше решения я обнаружил, что поле ввода чата по-прежнему плотно заблокировано, а метод ScrollIntoView() по-прежнему остается неподвижным. Я предполагаю, что на самом деле это связано с тем, что программная клавиатура прокручена вниз, а высота страницы больше, чем высота визуальной области, когда программная клавиатура появляется. Таким образом, высоту страницы можно принудительно увеличить только после этого. откроется программная клавиатура, и появится поле ввода. Учитывая вышеизложенное, он совместим со сторонними методами ввода. Чтобы просмотреть эффект, вы можете нажать здесь.
// Клавиатура Android убирается: высота страницы будет меняться, когда клавиатура Android выдвигается или убирается. Исходя из этого, известно, что клавиатура убирается, если (judgeDeviceType.isAndroid) { var originHeight = document.documentElement.clientHeight || document. body.clientHeight; window.addEventListener('resize', function () { var resizeHeight = document.documentElement.clientHeight || document.body.clientHeight; if (originHeight < resizeHeight) { console.log('Клавиатура Android закрыта!' // Исправлена проблема, связанная с тем, что поле ввода по-прежнему блокируется методом ввода в браузере Xiaomi if (judgeDeviceType.isMiuiBrowser) ) { document.body.style.marginBottom = '0px'; } } else { console.log('Всплывает клавиатура Android!'); // Устраните проблему, связанную с тем, что поле ввода все еще блокируется методом ввода в браузере Xiaomi if (judgeDeviceType.isMiuiBrowser) { document.body.style.marginBottom = '40px'; } activeElementScrollIntoView($input, 1000 } originHeight = resizeHeight; }, ЛОЖЬ )} Подвести итогКонцу H5 предстоит долгий путь и множество подводных камней, поэтому вам нужно продолжать попытки. Понимание разницы в производительности всплывающей страницы с программной клавиатурой на IOS и Android является обязательным условием. Второй шаг — прокрутка элемента фокуса до видимой области. В то же время различия в сторонних методах ввода и некоторых браузерах. необходимо принять во внимание.
Выше приведено все содержание этой статьи. Я надеюсь, что она будет полезна для изучения всеми. Я также надеюсь, что все поддержат сеть VeVb Wulin.