笔者最近开发完一个H5项目,在浏览器的模拟器中表现完美,可谁知到测试阶段,真机上却是漏洞百出。踩了许多的坑,于是痛定思痛,写下一篇文章来记录这些问题,与大家分享。
1. IOS高版本软键盘收回后,页面不会回到原位
在高版本的苹果手机上,软键盘弹出会使被遮盖的表单上移,但是软键盘收起却不能复原,这导致页面的焦点错乱,尤其在页面上有弹出层的时候。
这就需要在键盘收起后手动将页面复原
const isRest = false
document.body.addEventListener("focusin", () => {
//软键盘弹出的事件处理
isReset = false;
});
document.body.addEventListener("focusout", () => {
//软键盘收起的事件处理
isReset = true;
setTimeout(() => {
//当焦点在弹出层的输入框之间切换时先不归位
if (isReset) {
const bfscrolltop = document.body.scrollTop;
document.body.scrollTop = bfscrolltop;
}
}, 100);
});
2. 安卓点击软键盘确认键后无法使input焦点移出
因为笔者对表单的校验采用的是blur方式,但是在安卓机上点击软键盘确认按钮不会触发blur动作,这使得用户体验非常不好。
判断在安卓手机的情况下做如下处理:
const originalHeight = document.documentElement.clientHeight || document.body.clientHeight;
window.onresize = function() {
var resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
if (resizeHeight - 0 >= originalHeight - 0) {
document.activeElement.blur();
}
};
注:安卓手机不能使用focusout来监听软键盘收起,只能监听onresize事件。
3. 使用rem适配
设计团队的设计稿是基于iPhone6s做的,也就是长宽比为375:667。他们希望在其他设备上等比缩放。
所以我们使用了rem的方式,并且没有使用媒体查询在不同的宽度桑设置不同的font-size。而是使用了现有的轮子
;
(function (designWidth, maxWidth) {
var doc = document,
win = window,
docEl = doc.documentElement,
remStyle = document.createElement("style"),
tid;
function refreshRem() {
var width = docEl.getBoundingClientRect().width;
maxWidth = maxWidth || 540;
width > maxWidth && (width = maxWidth);
var rem = width * 16 / designWidth;
remStyle.innerHTML = 'html{font-size:' + rem + 'px;}';
}
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(remStyle);
} else {
var wrap = doc.createElement("div");
wrap.appendChild(remStyle);
doc.write(wrap.innerHTML);
wrap = null;
}
//要等 wiewport 设置好后才能执行 refreshRem,不然 refreshRem 会执行2次;
refreshRem();
win.addEventListener("resize", function () {
clearTimeout(tid); //防止执行两次
tid = setTimeout(refreshRem, 300);
}, false);
win.addEventListener("pageshow", function (e) {
if (e.persisted) { // 浏览器后退的时候重新计算
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
}, false);
if (doc.readyState === "complete") {
doc.body.style.fontSize = "16px";
} else {
doc.addEventListener("DOMContentLoaded", function (e) {
doc.body.style.fontSize = "16px";
}, false);
}
})(375, 750);
使用js动态计算,经测试这种方案效果最佳。
4. 滑动穿透问题
在移动端,弹出层的滑动会使得弹出层下端的页面跟着滚动,这给使用者造成了很不好的效果。 在社区针对这个问题有个很成熟的解决方案:
使用方式也很简单:
const bodyScrollLock = require('body-scroll-lock');
const disableBodyScroll = bodyScrollLock.disableBodyScroll;
const enableBodyScroll = bodyScrollLock.enableBodyScroll;
const targetElement = document.querySelector("#弹出层元素");
if(条件) disableBodyScroll(targetElement);
else enableBodyScroll(targetElement);
H5开发中最蛋疼的应该就是兼容性问题,这个过程很考验开发者的经验和耐心。
以上有什么不对的地方或更好的解决方案,欢迎大家留言交流。😄