总结一些h5出现的问题及解决方案
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
总结⼀些h5出现的问题及解决⽅案
1、ios的webview中滑动不流畅。
(原因:ios5.0以后的版本,滑动定义有两个值auto和touch。
默认值为auto)
-webkit-overflow-scrolling: touch; /* 当⼿指从触摸屏上移开,会保持⼀段时间的滚动 */
-webkit-overflow-scrolling: auto; /* 当⼿指从触摸屏上移开,滚动会⽴即停⽌ */
解决⽅案:
①、在滚动容器上增加滚动touch⽅法
.wrapper {
-webkit-overflow-scrolling: touch;
}
②、设置滚动条隐藏:
.container ::-webkit-scrollbar {display: none;}
可能会导致使⽤position:fixed;固定定位的元素,随着页⾯⼀起滚动
③、设置overflow
body {
overflow-y: hidden;
}
.wrapper {
overflow-y: auto;
}
设置之后,就会出现⼀个问题,ios上拉边界下拉出现⽩⾊空⽩
产⽣原因:在ios中,⼿指按住屏幕上下拖动,会触发touchmove事件。
这个时间触发的对象是整个view容器,容器⾃然会被拖动,剩下的部分会成空⽩。
解决⽅案:
①、监听事件禁⽌滚动
通过监听touchmove,让需要滑动的地⽅滑动,不需要滑动的地⽅禁⽌滑动(值得注意的是我们要过滤掉具有滚动容器的元素)。
document.body.addEventListener('touchmove', function(e) {
if(e._isScroller) return;
// 阻⽌默认事件
e.preventDefault();
}, {
passive: false
});
2、滚动拖鞋填充空⽩,装饰城其他功能(⽐如:下拉后刷新页⾯)
HTML 中meta元标签标准中有个viewport属性,⽤来控制页⾯的缩放,⼀般⽤于移动端,如下图:
移动端常规写法:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
因此我们可以设置maximum-scale、minimum-scale与user-scalable=no⽤来避免这个问题
<meta name=viewport
content="width=device-width, initial-scale=1.0, minimum-scale=1.0 maximum-scale=1.0, user-scalable=no">
3、软键盘将页⾯顶起来、收起未回落问题
原理与解决⽅案:
软键盘将页⾯顶起来的解决⽅案,主要是通过监听页⾯⾼度变化,强制恢复成弹出前的⾼度。
// 记录原有的视⼝⾼度
const originalHeight = document.body.clientHeight || document.documentElement.clientHeight;
window.onresize = function(){
var resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
if(resizeHeight < originalHeight ){
// 恢复内容区域⾼度
// const container = document.getElementById("container")
// 例如 container.style.height = originalHeight;
}
}
键盘不能回落问题出现在ios 12+和wechat6.7.4+中,⽽在微信h5开发中是⽐较常见额bug
兼容原理,判断版本类型,更改滚动的可视区域
const isWechat = erAgent.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));
}
注意:window.scrollTo(x-coord, y-coord),其中window.scrollTo(0, clientHeight)恢复成原来的视⼝
4、iphone X系列安全区域适配问题
产⽣的原因iphone X以及它以上的系列,都采⽤刘海屏设计和全⾯屏⼿势。
头部、底部、侧边都需要做特殊处理。
才能适配iPhone X的特殊情况。
解决⽅案:
①、设置安全区域,填充危险区域,危险区域不做操作和内容展⽰
②、viewport-fit meta标签设置问cover,获取所有区域填充。
判断设备是否属于iPhone X,给头部底部增加适配层
viewport-fit 有 3 个值分别为:
auto:此值不影响初始布局视图端⼝,并且整个web页⾯都是可查看的。
contain:视图端⼝按⽐例缩放,以适合显⽰内嵌的最⼤矩形。
cover:视图端⼝被缩放以填充设备显⽰。
强烈建议使⽤ safe area inset 变量,以确保重要内容不会出现在显⽰之外。
设置viewport-fit为cover
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes, 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);
}
}
注意:safe-area-inset-top, safe-area-inset-right, safe-area-inset-bottom, safe-area-inset-left safe-area-inset-*由四个定义了视⼝边缘内矩形的top, right, bottom和left的环境变量组成,这样可以安全地放⼊内容,⽽不会有被⾮矩形的显⽰切断的风险。
对于矩形视⼝,例如普通的笔记本电脑显⽰器,其值等于零。
对于⾮矩形显⽰器(如圆形表盘,iPhoneX屏幕),在⽤户代理设置的四个值形成的矩形内,所有内容均可见。
其中env()⽤法为env( <custom-ident> , <declaration-value>? ),第⼀个参数为⾃定义的区域,第⼆个为备⽤值。
其中var()⽤法为var( <custom-property-name> , <declaration-value>? ),作⽤是在env()不⽣效的情况下,给出⼀个备⽤值。
constant()被css 2017-2018 年为草稿阶段,是否已被标准化未知。
⽽其他iOS 浏览器版本中是否有此函数未知,作为兼容处理⽽添加进去。
5、页⾯⽣成为图⽚和⼆维码问题
①、使⽤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);
}
}
将await QRCode.toDataURL(url, options)赋值给图⽚url即可
②、⽣成图⽚:
主要是使⽤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());
}
根据需要设置scaleSize⼤⼩。