keyboard-height
Version:
calaculate the height of soft keyboard in mobile phone and emit on changes
74 lines (67 loc) • 2.37 kB
JavaScript
/**
* android 下用 innerHeight 对于新开 tab 会有问题,会把上面的导航条也算进去, toolbar 大约在 150 px 以内
* 即便在 DCL 下获取,也是有问题的,我们尝试在 1s 内轮训获取真实的 innerHeight
* 同时要避免 autoFocus 导致页面刚打开就谈键盘,引起计算 bug,同理,部分键盘上有刷新按钮,导致页面刚打开的 innerHeight 就不对
*/
let initialHeight = innerHeight;
let realInnerHeight = innerHeight; // 键盘未弹起时的高度
function reset() {
initialHeight = innerHeight;
realInnerHeight = innerHeight;
}
var lastScreenHeight = screen.height; // 用于探测是否旋转屏幕,只要是容器变了都算
const maxCheckTime = 10;
const toolbarMaxSize = 150;
let checkCnt = 0;
let callback = function () {};
const intval = setInterval(() => {
checkCnt++;
if (checkCnt > maxCheckTime) clearInterval(intval);
else {
const currentInnerHeight = innerHeight;
if (initialHeight - currentInnerHeight > toolbarMaxSize) return; // 可能键盘已经弹起
if (realInnerHeight === currentInnerHeight) return; // 无变化
realInnerHeight = currentInnerHeight;
// 通知
callback();
}
}, 100);
function isOrientationChanged() {
var changed = false;
if (!isSame(lastScreenHeight, screen.height)) {
changed = true;
lastScreenHeight = screen.height;
}
return changed;
}
function isSame(a, b) {
return Math.abs(a - b) < 0.01;
}
let lastHeight = -1;
export default function (cbArr) {
[];
callback = () => {
if (isOrientationChanged()) {
reset();
if (lastHeight > 0) realInnerHeight = innerHeight + lastHeight;
} else {
var delta = getAndroidHeight();
if (isSame(delta, lastHeight)) return;
lastHeight = delta;
cbArr.forEach((cb) => {
cb.call(null, lastHeight);
});
}
};
window.addEventListener("resize", callback);
}
export function getAndroidHeight() {
const currentInnerHeight = innerHeight;
// 理论上讲 realInnerHeight 应该是个定值,但考虑到初始化的时候键盘就弹起的情形,该逻辑用来纠偏
if (currentInnerHeight > realInnerHeight && checkCnt >= maxCheckTime)
realInnerHeight = currentInnerHeight;
return realInnerHeight - currentInnerHeight;
}
export function getAndroidInnerHight() {
return realInnerHeight;
}