mianyue502 / blog

Lynne's Blog
0 stars 0 forks source link

4. 移动端键盘弹起与收起的不同与兼容 #4

Open mianyue502 opened 4 years ago

mianyue502 commented 4 years ago

IOS键盘弹起与收起: 1) 弹起表现:点击输入框时,输入框获取焦点(触发focus),键盘弹起,页面整体上移(页面高度未变);会将获取焦点元素滚动到可视区; 2) 收起表现:点击输入框以外任意区域/点击键盘“完成”时,输入框失去焦点(触发blur),键盘收起,但是页面不会回到原来的位置。

安卓键盘弹起与收起: 1) 弹起表现:点击输入框时,输入框获取焦点(触发focus),键盘弹起(触发focus),页面高度发生改变(此时页面高度为原高度 - 键盘高度);不会将获取焦点元素滚动到可视区; 2) 收起表现:点击输入框以外任意区域时,输入框失去焦点(触发blur),键盘收起;点击键盘“收起”时,键盘收起,但是输入框不会失去焦点(未触发blur)。 页面不会回到原来的位置。

键盘弹起与收起的监听: IOS可直接监听输入框的input和blur事件知道键盘的弹起与收起; 安卓则需要通过监听文档的resize事件知道键盘的弹起与收起;

const isiOS = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
const input = document.querySelector('input') as HTMLElement;

if(isiOS){
    input.addEventListener('focus', function () {
        console.log('IOS键盘弹起');
      }, false);
    input.addEventListener('blur', function () {
        console.log('IOS键盘收起');
    }, false)
} else {
    const originHeight = document.documentElement.clientHeight || document.body.clientHeight;
    window.addEventListener('resize', () => {
      const resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
      if (resizeHeight < originHeight) {
        console.log('Andriod键盘弹起');
      } else {
        console.log('Andriod键盘收起');
      }
    }, false);
}

兼容实现键盘弹起元素滚动到可视区、键盘收起失去焦点且页面回到原来位置:

const isIos = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
const input = document.querySelector('input');
let timer = null;
let height = 0;
const scrollTo = function() {
    clearTimeout(timer);
    timer = setTimeout(() => {
        window.scroll(0, height);
    }, 100);
};
const blurHandler = function() {
    scrollTo();
};
const focusHandler = function() {
    clearTimeout(timer);
    const scrollTop = document.body.scrollTop == 0 ? document.documentElement.scrollTop : document.body.scrollTop;
    height = +(scrollTop + '').replace('px', '');
};
if(isIos){
    input.addEventListener('focus', focusHandler);
    input.addEventListener('blur', blurHandler);
} else {
    const originHeight = document.documentElement.clientHeight || document.body.clientHeight;
    window.addEventListener('resize', () => {
        const resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
        if (resizeHeight < originHeight) {
            focusHandler();
            setTimeout(function () {
                input.scrollIntoView();
            }, 100)

        } else {
            blurHandler();
        }
    }, false);
}