H5软键盘兼容方案

在 Android 和 IOS 上,获知软键盘弹起和收起状态存在差异,且页面 webview 表现不同。


软键盘弹起表现

  • 期望
    输入框获取焦点,键盘弹起,页面(webview)并没有被压缩,或者说高度(height)没有改变,只是页面(webview)整体往上滚动。焦点元素会滚动到可视区域。
  • 在IOS部分版本(12) 上,当键盘收起后,页面不回到原位,导致键盘原来所在位置空白。
  • 在 Android部分机型上,输入框获取焦点,键盘弹起,但是页面(webview)高度会发生改变,一般来说,高度为可视区高度(原高度减去软键盘高度),可能产生滚动,但webview 本身不能滚动。

软键盘收起表现

  • IOS 触发软键盘上的“收起”按钮键盘或者输入框以外的页面区域时,输入框失去焦点,软键盘收起。
  • Android 触发输入框以外的区域时,输入框失去焦点,软键盘收起。但是,触发键盘上的收起按钮键盘时,输入框并不会失去焦点,同样软键盘收起。


    H5软键盘兼容方案_第1张图片
    软键盘弹起表现

监听软键盘弹起和收起

  • 在 IOS 上,监听输入框的 focus 事件来获知软键盘弹起,监听输入框的 blur 事件获知软键盘收起。
  • 在 Android 上,监听 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
  }
}()
// 监听输入框的软键盘弹起和收起事件
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)
  }
}
var $inputs = document.querySelectorAll('.input');
for (var i = 0; i < $inputs.length; i++) {
  listenKeybord($inputs[i]);
}

弹起软键盘始终让输入框滚动到可视区

IOS本身即有该功能,因此只需在 Android 键盘弹起后,将焦点元素滚动到可视区。

// 获取到焦点元素滚动到可视区
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);
// ...

兼容 IOS12 + V6.7.4+ 键盘收起时底部空白问题

H5软键盘兼容方案_第2张图片
键盘收起时底部空白
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));
  })
}
  • 简易方法: 在input的blur事件中添加如下内容
  setTimeout(function () {
    window.scrollTo(0, Math.max(document.body.clientHeight, document.documentElement.clientHeight));
  })

使用setTimeout的目的是防止因页面直接滚动导致触发blur时的点击无效化

你可能感兴趣的:(H5软键盘兼容方案)