H5 手机键盘兼容

文章目录

  • 键盘弹起页面表现
    • ios表现
    • 安卓表现
  • 监听软键盘弹起和收起
    • ios监听focus、blur事件
    • 安卓还可见监听页面高度
  • 获取软键盘高度
    • 通过window.visualViewport异步获取
  • 唤起软键盘始终让焦点元素滚动到可视区
    • document.activeElement配合scrollIntoView()
  • 某些版本键盘收起,但页面未恢复

键盘弹起页面表现

  • ios表现

    • 是页面(webview)整体往上滚了,且最大滚动高度(scrollTop)为软键盘高度。
  • 安卓表现

    • 页面(webview)高度会发生改变,一般来说,高度为可视区高度(原高度减去软键盘高度)

监听软键盘弹起和收起

// 判断设备类型
var judgeDeviceType = function () {
  var ua = window.navigator.userAgent.toLocaleLowerCase();
  var isIOS = /iphone|ipad|ipod/.test(ua);
  var isAndroid = /android/.test(ua);

  return {
    isIOS: isIOS,
    isAndroid: isAndroid
  }
}()
  • ios监听focus、blur事件

// 监听输入框的软键盘弹起和收起事件
function 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 键盘收起后操作
    })
  }
  • 安卓还可见监听页面高度

 // Andriod 键盘收起:Andriod 键盘弹起或收起页面高度会发生变化,以此为依据获知键盘收起
  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)
  }
}

获取软键盘高度

  • 通过window.visualViewport异步获取

 //异步是因为键盘唤起有动画时间
 setTimeout(() => {
   this.keyBoardHeight = window.innerHeight - window.visualViewport.height;
 }, 800);

唤起软键盘始终让焦点元素滚动到可视区

  • 当输入框位于页面下部位置时,在 ios 上,会将 webview 整体往上滚一段距离,使得该获取焦点的输入框自动处于可视区,而在 Android 则不会这样,它只会改变页面高度,而不会去滚动到当前焦点元素到可视区。
  • document.activeElement配合scrollIntoView()

// 获取到焦点元素滚动到可视区
function activeElementScrollIntoView(activeElement, delay) {
  var editable = activeElement.getAttribute('contenteditable')

  // 输入框、textarea或富文本获取焦点后没有将该元素滚动到可视区
  if (activeElement.tagName == 'INPUT' || activeElement.tagName == 'TEXTAREA' || editable === '' || editable) {
    setTimeout(function () {
      activeElement.scrollIntoView();
    }, delay)
  }
}

// ...
// Android 键盘弹起后操作
activeElementScrollIntoView($input, 1000);
// ...

某些版本键盘收起,但页面未恢复

  • 在软键盘收起后,将页面(webview)滚回到窗口最底部位置(clientHeight位置)
console.log('IOS 键盘收起啦!');
// IOS 键盘收起后操作
// 微信浏览器版本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) {
  setTimeout(function () {
    window.scrollTo(0, Math.max(document.body.clientHeight, document.documentElement.clientHeight));
  })
}

你可能感兴趣的:(移动端与REM,android,javascript,ios)