总结一些h5出现的问题及解决方案

Posted chao202426

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了总结一些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 = 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));
}

注意: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-topsafe-area-inset-rightsafe-area-inset-bottomsafe-area-inset-left safe-area-inset-*由四个定义了视口边缘内矩形的 toprightbottom 和 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 大小

 

以上是关于总结一些h5出现的问题及解决方案的主要内容,如果未能解决你的问题,请参考以下文章

H5的兼容问题总结

安卓APP加载HTML5页面解决方案总结

安卓APP载入HTML5页面解决方式总结

安卓APP加载HTML5页面解决方案总结

H5常见问题及解决方案手册

单页应用如何调用微信接口和手机端的一些方法?