Проблемы с мягкой клавиатурой и решения, которые вызывают боль на мобильном терминале

внешний интерфейс
Проблемы с мягкой клавиатурой и решения, которые вызывают боль на мобильном терминале

вопрос

Описание проблемы:

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

Гифка выглядит следующим образом:

1.gif

Пункт, который пользовательский интерфейс хочет оптимизировать:

В начале ui предложил 3 точки оптимизации для проблем в этом видео:

1. Я надеюсь, что элементы потолка могут продолжаться до потолка

2. Я надеюсь, что элементы, поглощающие дно, могут продолжать поглощать дно.

3. Я надеюсь, что когда клавиатура всплывает, поле ввода может поддерживать расстояние 48 пикселей над клавиатурой.

Конечная точка оптимизации решения:

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

1. Потолочный элемент может продолжаться до потолка

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

3. Клавиатура всплывает, и поле ввода появляется в видимой области. (Для этого сама ios поддерживает, но Android активно не заставляет поле ввода появляться в видимой области)

4. Для некоторых веб-просмотров WeChat в некоторых системах ios обнаружено, что при сложенной программной клавиатуре страница, прокручиваемая вверх, не прокручивается вниз, в результате чего в области внизу остается серая область.

Вопросы, которые нужно понять в первую очередь

Прежде чем решать эти задачи, нужно разобраться в следующих 2-х проблемах:

1. Что происходит, когда появляется клавиатура

Здесь производительность систем iOS и Android несовместима. Это относится к этой статье, предоставленной Zhu Lei:Совместимая схема программной клавиатуры в WebView

Производительность всплывающих окон программной клавиатуры IOS

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

Производительность всплывающих окон программной клавиатуры Android

Точно так же на Android поле ввода получает фокус и появляется клавиатура, но высота страницы (веб-просмотра) изменится.. Вообще говоря, высота — это высота области просмотра (исходная высота минус высота программная клавиатура), за исключением того, что содержимое страницы Spreading может генерировать прокрутку, сам веб-просмотр не может прокручиваться.

Производительность при сворачивании мягкой клавиатуры IOS

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

Производительность при сворачивании мягкой клавиатуры Android

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

image.png

image.png

2. Почему исправление не работает

Поскольку страница перемещается вверх, когда появляется клавиатура ios, почему исправление не работает?

Обратитесь к этой статье здесь:Загадка клавиатуры ios с видимым окном просмотра (visualViewport) API

В то время разработчики ios рассматривали проблему: когда клавиатура всплывает, страница не может воспринимать существование клавиатуры. Итак, не было бы плохим опытом, если цель, которую нужно ввести (т. е. «поле ввода», такое как поле ввода, текстовая область или элемент, доступный для редактирования в целом), оказывается скрытой всплывающей клавиатурой?

Чтобы решить эту проблему, дизайнеры ios сделали прокрутку webview вверх, но результат прокрутки оказался несколько неожиданным: само поле ввода по понятным причинам прокручивалось до середины реальной просматриваемой области, но фиксированный элемент не пересчитывался, а сохранял исходное относительное положение и сдвигается вверх вместе с полем ввода; в процессе прокрутки нижняя часть экрана также может выходить за пределы нижней части страницы («прокручивать»), чтобы поле ввода было максимально открыто . После закрытия клавиатуры часть "overscroll" отскочит назад, фиксированный элемент будет пересчитан, но страница не вернется в то же положение, что и до открытия клавиатуры.

3. Как следить за тем, как клавиатура выдвигается и убирается

Поскольку это проблема, вызванная отскоком клавиатуры, то для решения этой проблемы необходимо отслеживать движения отскока и втягивания клавиатуры, так как это контролировать. Также обратитесь к этой статье:Совместимая схема программной клавиатуры в WebView

Объединив различные характеристики вышеупомянутого всплывающего окна и втягивания клавиатуры в IOS и Android, мы можем отдельно выполнить следующую обработку для отслеживания всплывающего окна и втягивания программной клавиатуры:

Ios

В IOS прослушивайте событие focus поля ввода, чтобы знать, что виртуальная клавиатура всплывает, и прослушивайте событие blur в поле ввода, чтобы знать, что программная клавиатура убрана. На Android отслеживайте высоту веб-просмотра, чтобы измениться, и высота становится меньше, чтобы знать, что программная клавиатура всплывает, иначе программная клавиатура убирается.

// IOS 键盘弹起:当输入框被聚焦时IOS键盘会被弹起
  inputRef?.current?.addEventListener('focus', function () {
    // IOS 键盘弹起后操作
  }, false)

  // IOS 键盘收起:当点击输入框以外区域或点击收起按钮,IOS输入框都会失去焦点,键盘会收起,
  inputRef?.current?.addEventListener('blur', () => {
    // IOS 键盘收起后操作
  })

android

На Android следите за изменением высоты веб-просмотра, и когда высота станет меньше, всплывет программная клавиатура, иначе программная клавиатура будет убрана.

useEffect(() => {
    const { isAndroid } = Util.getOS('');
    let originHeight = document.documentElement.clientHeight || document.body.clientHeight;
    const handelAndroidResize = throttle(() => {
        const resizeHeight =
            document.documentElement.clientHeight || document.body.clientHeight;
        if (originHeight < resizeHeight) {
            // Android 键盘收起后操作
        } else {
            // Android 键盘弹起后操作
        }
        originHeight = resizeHeight;
    }, 300);

    if (isAndroid) {
        window.addEventListener('resize', handelAndroidResize, false);
    }

    return () => {
        if (isAndroid) {
            window.removeEventListener('resize', handelAndroidResize, false);
        }
    };
  }, []);

Решение

Давайте начнем анализировать и решать проблемы, упомянутые выше, одну за другой:

1. Потолочный элемент может продолжаться до потолка

Эта проблема возникает только в системе ios, потому что клавиатура всплывает в ios и android по-разному.

В то время я искал решение, и я чувствовал, что подходящего решения нет, поэтому я сделал следующий шаг.Поскольку у h5 нет возможности хорошо решить проблему подсоса потолка, то эта способность хуже, чем использование Способность клиента Заголовок клиента не принадлежит к Когда содержимое веб-просмотра естественным образом выталкивается вверх, заголовок клиента все еще находится в состоянии потолка.

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

Производные вопросы:

Но это приводит к новой проблеме: на стороне приложения в системе Android возникает проблема, заключающаяся в том, что нижняя кнопка заблокирована.

Гифка выглядит следующим образом:

2.gif

Производные решения проблем

Раньше, когда шапка шапки писалась самим фронтендом, такой проблемы не было, есть предположение, что высота вебвью Android-телефона при всплывающей клавиатуре укорачивается до высоты всего экрана минус высота клавиатуры.В предыдущей реализации из-за использования иммерсивного заголовка, поэтому высота внешнего веб-просмотра равна высоте всего экрана, а теперь, поскольку используется возможность jsb на стороне клиента, оставшиеся высота веб-просмотра должна быть вычтена из высоты заголовка. Таким образом, решение состоит в том, чтобы добавить нижнюю кнопку всасывания и нижний край нижнего элемента к высоте заголовка, когда клавиатура всплывает.

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

Для этой проблемы, поскольку производительность Android заключается в том, что веб-просмотр сжимается, этой проблемы не существует на Android.Для ios, поскольку максимальное расстояние прокрутки ios - это высота клавиатуры, но также возможно, что расстояние прокрутки не высота клавиатуры, в результате чего нижняя всасывающая кнопка заблокирована.

Видимый GIF выглядит следующим образом:

RPReplay_Final1620886689.gif

Решение:

Когда появится клавиатура, добавьте метод scrollIntoView(true); в поле ввода. На самом деле это может относиться только к моей ситуации.Принцип этого решения: scrollIntoView(true) заставляет верхнюю часть поля ввода прокручиваться на одном уровне с верхней частью визуальной области, но из-за максимального расстояния прокрутки после Клавиатура ios всплывает Она равна высоте клавиатуры, поэтому с помощью этого метода расстояние прокрутки веб-просмотра будет равно высоте клавиатуры ios, что обеспечивает эффект присасывания кнопки снизу.

3. Клавиатура всплывает, и поле ввода появляется в видимой области. (Для этого сама ios поддерживает, но Android активно не заставляет поле ввода появляться в видимой области)

Это просто, пусть элемент прокручивается в видимую область, просто используйте метод scrollIntoView(true) напрямую.

4. Страница не может скользить вниз естественным образом, когда программная клавиатура ios закрыта.

Для некоторых веб-просмотров WeChat в некоторых системах ios было обнаружено, что, когда виртуальная клавиатура сложена, прокручиваемая страница не прокручивается вниз, в результате чего в области ниже появляется серая область. На самом деле это ошибка Apple в IOS, которая появится на всех устройствах IOS12, упакованных с Xcode10. Официальный представитель WeChat дал решение (Нажмите, чтобы просмотреть).

Гифка вопроса:

videoCacheAB76944E-B51D-4FB2-89FC-D5EF2079C6CC.gif

как показано на рисунке:

image.png

Решение:

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

  1. пролистать наверх
window.scrollTo(0,0)
  1. прокрутить вниз
window.scrollTo(0, Math.max(document.body.clientHeight, document.documentElement.clientHeight));

Код для этой сцены

const handleIosInputBlur = () => {
    // IOS 键盘收起后操作
    // 微信浏览器版本6.7.4+IOS12会出现键盘收起后,视图被顶上去了没有下来
    const wechatInfoRe = /MicroMessenger\/([\d\.]+)/i;
    const wechatInfo = wechatInfoRe.exec(window?.navigator?.userAgent);
    const wechatVersion = wechatInfo && wechatInfo.length > 1 && wechatInfo[1];

    const osInfoRe = /OS (\d+)_(\d+)_?(\d+)?/i;
    const osInfo = osInfoRe.exec(navigator.appVersion);
    const osVersion = osInfo && osInfo.length > 1 && osInfo[1];

    if (!wechatVersion || !osVersion) {
        return;
    }
    const height = Math.max(document.body.clientHeight, document.documentElement.clientHeight);
        if (Number(wechatVersion.replace(/\./g, '')) >= 674 && Number(osVersion) >= 12) {
            window.scrollTo(0, height);
        }
    };

окончательный эффект:

Ios

4.gif

андроид

5.gif

Справочная статья:

Совместимая схема программной клавиатуры в WebView

js как получить высоту клавиатуры iOS

Распространенные проблемы и решения мобильного ввода «ящик ввода»

Загадка клавиатуры ios с видимым окном просмотра (visualViewport) API

❤️ Спасибо за поддержку

Выше приведено все содержание этого обмена, я надеюсь, что это поможет вам ^_^

Не забудьте, если вам нравитсяПоделиться, Нравится, ИзбранноеТри последовательных о~.

Добро пожаловать в публичный аккаунтКоманда ELabХорошая статья от принимающей фабрики~