Обнаружение виртуальной клавиатуры на экране и альбомной ориентации в javascript

Я работаю на HTML-код на основе мобильного приложения, где есть требования к дизайну приложения только для портретной ориентации, и отобразить сообщение пользователю, когда он идет на пейзаж, эта функция работает нормально, с помощью CSS медиа-запросов, но проблема в том, что у меня есть форма в приложении, и когда я нажимаю на текстовое поле и виртуальная клавиатура открывает и высота экрана меняется и он показывает мне сообщение для изменения ориентации

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

@media screen and (orientation: landscape) {

}

Я проверил другие вопросы, связанные с моей темой на stackoverflow, но ничего полезного там

3 ответов


короткий ответ:

нет, к сожалению, нет текущего способа определить, когда виртуальная клавиатура появляется на экране. Обнаружение ориентации да, это возможно с помощью:

  1. Media-запросы CSS (согласно вашему примеру)
  2. через JavaScript с помощью orientationchange слушатель.
  3. через JavaScript с помощью resize слушатель и вывод ориентации с помощью window.innerHeight > window.innerWidth

длинные ответ:

не должно быть причин, по которым клавиатура влияет на orientation свойство, которое интерпретируется вашим медиа-запросом css следующим образом:

@media screen and (orientation: landscape) {
    ...
}

организация W3C media queries recomendation заявляет следующее для orientation свойства:

функция "ориентация" - это "портрет", когда значение функции "высота" больше или равно значению функции "ширина". Иначе "ориентация" - это "пейзаж".

клавиатура, видимая при вводе в текстовом поле формы, просто не должна вызывать orientation свойство меняться.

у меня в прошлом была ваша проблема при использовании эмуляторов устройств, таких как режим устройства в старых версиях devtools Google Chrome. Однако, когда он был протестирован на реальном мобильном устройстве, проблема не возникла.

кроме того, есть этот ошибка открыть в мобильном chrome, который может вызывать события изменения размера при появлении клавиатуры.

возможно, эмулятор, если это то, что вы используете, неправильно вызывает изменение высоты видовых экранов, поэтому вызывает изменение orientationсвойства в запросе СМИ.

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

  1. когда мобильное устройство находится в портретная ориентация на экране отображаются два поля ввода формы (отображаются слова: "foo" и "baz").
  2. когда я касаюсь любого из полей ввода формы, отображается клавиатура, и содержимое страницы не изменяется.
  3. когда устройство повернуто на 90 градусов к альбомной ориентации появляется серая панель, показывающая слова:"Поверните устройство к портрету"

Примечание: шаги, перечисленные выше, - это то, что происходит, когда тестирование gist ниже на нескольких реальных мобильных устройствах под управлением Safari на iOS и mobile Chrome на Android (...не эмуляторы!).

<!DOCTYPE html>

<html lang="en">

<head>
    <meta charset="utf-8" />
    <title>StackOveflow question 40175207</title>
    <meta name="description" content="Example gist using orientation css media query to hsow message when device is landscape" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
<style type="text/css">

body {
    padding: 0;
    margin: 0;
}

.wrapper {
    position: absolute;
    width: 100%;
    height: 100%;
    overflow: hidden;
    padding: 0;
    margin: 0;
}

.message-panel {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: gray;
    -webkit-transform: translateX(100%);
            transform: translateX(100%);

    will-change: transform;
}

.message-panel__text {
    position: absolute;
    top: 50%;
    text-align: center;
    font: 1em Helvetica, sans-serif;
    width: 100%;
    height: 50px;
    margin: auto;
    -webkit-transform: translateX(-50%);
            transform: translateY(-50%);
}

@media screen and (orientation: landscape) {
    .message-panel {
        transform: translateX(0);
    }
}

</style>

</head>
<body>
    <div class="wrapper">
        <form>
            <input type="text" name="input-one" value="foo">
            <input type="text" name="input-two" value="baz">
        </form>
        <div class="message-panel">
            <div class="message-panel__text">Rotate your device to portrait</div>
        </div>
    </div>
</body>
</html>

PS: существует также веб-приложение манифест в Chrome для Android, который позволяет заблокировать ориентацию устройства тоже. См.здесь для получения дополнительной информации.

надеюсь, что это помогает!


вы не можете определить, есть или нет виртуальная клавиатура только с помощью CSS. Вам нужно будет использовать javascript.

Если вы используете Cordova для создания приложения, попробуйте использовать плагин клавиатуры. Он запускает событие всякий раз, когда клавиатура отображается или скрыта, так что вы можете как-то ответить на него, т. е. добавьте класс в <body> это предотвратит отображение сообщения.

https://github.com/driftyco/ionic-plugin-keyboard

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

$(document.body).on("focus", "textarea, input", function() {
   $(document.body).addClass("do-not-show-message");
}).on("blur", "textarea, input", function() {
   $(document.body).removeClass("do-not-show-message");
});;

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

  • Flexbox для макета
  • Высота flexbox установлена в 100vh.
  • поскольку 100vh проблематично в Safari, обнаружьте Safari с js и установите значение 100%

вот скрипка, которая показывает мое решение

var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
if (isSafari) {
  document.body.className = "is-safari";
}
html,
body {
  padding: 0;
  margin: 0;
}
.chat {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: stretch;
  align-content: stretch;
  width: 100%;
  height: 100vh;
  background: white;
}
.is-safari .chat {
  height: 100%;
}
.chat__header,
.chat__footer {
  background: whitesmoke;
  height: 60px;
}
.chat__body {
  flex: 1;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Chat View</title>
</head>

<body>
  <div class="chat">
    <div class="chat__header">Header</div>
    <div class="chat__body">Body</div>
    <div class="chat__footer">Footer</div>
  </div>
</body>

</html>