前言
在我们开发H5页面的时候必会遇到一些兼容性等爬过坑的问题,在这里我将这些问题汇总一下,自己也做一下笔记
问题:
1,ios滑动不流畅 2,ios上拉边界下拉出现白色空白 3,页面件放大或缩小不确定性行为 4,click点击穿透与延迟 5,软键盘弹出将页面顶起,收起未回落问题(导致整体页面上移) 6,iphonex 底部栏适配问题 7,保存页面为图片和二维码问题和解决方案 8,微信公众号H5分享问题
移动端H5相关基础技术:
ios滑动不流畅
上下滑动页面会产生卡顿,手指离开页面,页面立即停止运动。整体表现就是滑动不流畅,没有滑动惯性。
原来在 iOS 5.0 以及之后的版本,滑动有定义有两个值 auto 和 touch,默认值为 auto。
-webkit-overflow-scrolling: touch; /* 当手指从触摸屏上移开,会保持一段时间的滚动 */
-webkit-overflow-scrolling: auto; /* 当手指从触摸屏上移开,滚动会立即停止 */
解决方案: 1.在滚动容器上增加滚动 touch 方法
将-webkit-overflow-scrolling 值设置为 touch
.wrapper { -webkit-overflow-scrolling: touch; } 设置滚动条隐藏: .container ::-webkit-scrollbar {display: none;} 可能会导致使用position:fixed; 固定定位的元素,随着页面一起滚动
2.设置 overflow
设置外部 overflow 为 hidden,设置内容元素 overflow 为 auto。内部元素超出 body 即产生滚动,超出的部分 body 隐藏。
body { overflow-y: hidden; } .wrapper { overflow-y: auto; } 两者结合使用更佳!
iOS 上拉边界下拉出现白色空白
手指按住屏幕下拉,屏幕顶部会多出一块白色区域。手指按住屏幕上拉,底部多出一块白色区域。
产生原因: 在 iOS 中,手指按住屏幕上下拖动,会触发 touchmove 事件。这个事件触发的对象是整个 webview 容器,容器自然会被拖动,剩下的部分会成空白。
解决:
document.body.addEventListener('touchmove', function(e) {
if(e._isScroller) return;
// 阻止默认事件
e.preventDefault();
}, {
passive: false
});
页面放大或缩小不确定性行为
双击或者双指张开手指页面元素,页面会放大或缩小。
解决:
或者:
click 点击事件延时与穿透
监听元素 click 事件,点击元素触发时间延迟约 300ms。
点击蒙层,蒙层消失后,下层元素点击触发。
解决: 1,,使用 touchstart 替换 click
移动设备不仅支持点击,还支持几个触摸事件。那么我们现在基本思路就是用 touch 事件代替click 事件。 将 click 替换成 touchstart 不仅解决了 click 事件都延时问题,还解决了穿透问题。因为穿透问题是在 touch 和 click 混用时产生。
在原生中使用
el.addEventListener(“touchstart”, () => { console.log(“ok”); }, false);
在 vue 中使用
点击
2,使用 fastclick 库
import FastClick from ‘fastclick’;
FastClick.attach(document.body, options);
软键盘将页面顶起来、收起未回落问题
因为input事件将软键盘弹出,当软键盘回收的时候页面没有回落,底下出现一片空白的地方
解决:
const isWechat = window.navigator.userAgent.match(/MicroMessenger\/([\d\.]+)/i);
if (!isWechat) return;
const wechatVersion = wechatInfo[1];
const version = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
// 如果设备类型为iOS 12+ 和wechat 6.7.4+,恢复成原来的视口
if (+wechatVersion.replace(/\./g, '') >= 674 && +version[1] >= 12) {
window.scrollTo(0, Math.max(document.body.clientHeight, document.documentElement.clientHeight));
}
iPhone X系列安全区域适配问题
头部刘海两侧区域或者底部区域,出现刘海遮挡文字,或者呈现黑底或白底空白区域。
解决: 设置安全区域,填充危险区域,危险区域不做操作和内容展示。 viewport-fit meta 标签设置为 cover,获取所有区域填充。判断设备是否属于 iPhone X,给头部底部增加适配层
viewport-fit 有 3 个值分别为: auto:此值不影响初始布局视图端口,并且整个web页面都是可查看的。 contain:视图端口按比例缩放,以适合显示内嵌的最大矩形。 cover:视图端口被缩放以填充设备显示。强烈建议使用 safe area inset 变量,以确保重要内容不会出现在显示之外。 设置 viewport-fit 为 cover
增加适配层
使用 safe area inset 变量
/* 适配 iPhone X 顶部填充*/ @supports (top: env(safe-area-inset-top)){ body, .header{ padding-top: constant(safe-area-inset-top, 40px); padding-top: env(safe-area-inset-top, 40px); padding-top: var(safe-area-inset-top, 40px); } } /* 判断iPhoneX 将 footer 的 padding-bottom 填充到最底部 */ @supports (bottom: env(safe-area-inset-bottom)){ body, .footer{ padding-bottom: constant(safe-area-inset-bottom, 20px); padding-bottom: env(safe-area-inset-bottom, 20px); padding-top: var(safe-area-inset-bottom, 20px); }
页面生成为图片和二维码问题
生成二维码
使用 QRCode 生成二维码
import QRCode from ‘qrcode’; // 使用 async 生成图片 const options = {}; const url = window.location.href; async url => { try { console.log(await QRCode.toDataURL(url, options)) } catch (err) { console.error(err); } }
生成图片
主要是使用 htmlToCanvas 生成 canvas 画布
import html2canvas from ‘html2canvas’;
html2canvas(document.body).then(function(canvas) { document.body.appendChild(canvas); }); 但是不单单在此处就完了,由于是 canvas 的原因。移动端生成出来的图片比较模糊。
我们使用一个新的 canvas 方法多倍生成,放入一倍容器里面,达到更加清晰的效果,通过超链接下载图片 下载文件简单实现,更完整的实现方式之后更新
const scaleSize = 2; const newCanvas = document.createElement(“canvas”); const target = document.querySelector(‘div’); const width = parseInt(window.getComputedStyle(target).width); const height = parseInt(window.getComputedStyle(target).height); newCanvas.width = width * scaleSize; newCanvas.height = widthh * scaleSize; newCanvas.style.width = width + “px”; newCanvas.style.height =width + “px”; const context = newCanvas.getContext(“2d”); context.scale(scaleSize, scaleSize); html2canvas(document.querySelector(’.demo’), { canvas: newCanvas }).then(function(canvas) { // 简单的通过超链接设置下载功能 document.querySelector(".btn").setAttribute(‘href’, canvas.toDataURL()); } 生成图片也可以使用htnl2canvas
微信公众号分享问题
在微信公众号 H5 开发中,页面内部点击分享按钮调用 SDK,方法不生效。 解决方法:添加一层蒙层,做分享引导。 也可以在公共的地方添加一个总的分享