在javascript中检测屏幕上的虚拟键盘和横向方向

时间:2016-10-21 11:13:59

标签: javascript html css mobile

正在开发一个基于html的移动应用程序,其中需要设计仅用于纵向的应用程序并在用户进入横向时向用户显示消息,此功能在css媒体查询中工作正常但问题是我有一个在应用程序中的表单,当我点击任何文本框和虚拟键盘打开和屏幕高度更改,它显示我的方向更改消息

现在我想询问实际方向更改以及屏幕上出现虚拟键盘时是否有任何不同之处。 提前致谢

@media screen and (orientation: landscape) {

}

我已经检查了与stackoverflow上的主题相关的其他问题,但没有任何帮助

3 个答案:

答案 0 :(得分:4)

您无法仅使用CSS检测虚拟键盘是否存在。您需要使用一些javascript。

如果您使用Cordova构建应用程序,请尝试使用Keyboard插件。它会在显示或隐藏键盘时触发事件,以便您可以以某种方式响应它,即。将一些类添加到<body>,这将阻止显示该消息。

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

另一种方法是倾听&#34;焦点&#34;所有可能导致键盘出现的元素的事件。

$(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");
});;

答案 1 :(得分:4)

答案简短:

不,遗憾的是,目前无法检测虚拟键盘何时出现在屏幕上。检测方向是,可以使用:

  1. css媒体查询(根据您的示例
  2. 使用orientationchange侦听器通过JavaScript。
  3. 使用resize侦听器通过JavaScript并使用window.innerHeight > window.innerWidth
  4. 推断方向

    答案很长:

    键盘不应该影响css媒体查询解释的orientation属性,如下所示:

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

    W3C media queries recomendation声明orientation属性的以下内容:

      

    当“高度”媒体要素的值大于或等于“宽度”媒体要素的值时,“方向”媒体要素为“纵向”。否则'方向'是'风景'。

    键入表单文本框字段时键盘可见,不应触发orientation属性更改。

    我过去在使用设备模拟器时遇到了问题,例如旧版谷歌Chrome浏览器的设备模式。但是,当它在真实的移动设备上进行测试时,问题没有发生。

    此外,在移动设备上打开此bug可能会导致键盘出现时触发调整大小事件。

    如果您使用的是仿真器,则错误地导致视口高度发生变化,从而导致更改媒体查询中的orientation属性。

    我在下面提供的简单要点执行以下操作(您可以尝试在开发环境中运行它以查看发生的情况):

    1. 当移动设备处于纵向方向时,屏幕会显示两个表单输入字段(显示单词:&#39; foo&#39;和&#39; baz&#39;)。
    2. 当我触摸任何一个表单输入字段时,键盘会显示,并且页面内容没有变化。
    3. 当设备旋转90度到横向时,会出现一个灰色面板,显示单词:&#34;将设备旋转为纵向&#34;
    4. 注意:上面列出的步骤是在iOS上运行Safari并在Android上运行Chrome的几个真实移动设备上测试下面的要点时发生的事情(...不是模拟器!)。

      <!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 for Android中还有Web App Manifest,它允许您锁定设备的方向。有关详细信息,请参阅here

      希望这有帮助!

答案 2 :(得分:1)

我在使用HTML设计聊天视图时遇到了麻烦。顶部的标题,内容中心和底部的聊天字段。最后,这是我选择的解决方案

  • 用于布局的Flexbox
  • 弹性箱的高度设置为100vh。
  • 由于100vh在Safari中存在问题,因此请使用js检测Safari并将其设置为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>