移动端常见兼容问题

7/4/2020 h5

# ios取消input在输入时首字母默认大写

<input type="text" autocapitalize="off">
1

# iOS 滑动不流畅

ios 手机上下滑动页面会产生卡顿,手指离开页面,页面立即停止运动。整体表现就是滑动不流畅,没有滑动惯性。 iOS 5.0 以及之后的版本,滑动有定义有两个值 auto 和 touch,默认值为 auto。

  1. 在滚动容器上设置
.wrapper{
  -webkit-overflow-scrolling:touch
}
1
2
3
-webkit-overflow-scrolling: touch; /* 当手指从触摸屏上移开,会保持一段时间的滚动 */

-webkit-overflow-scrolling: auto; /* 当手指从触摸屏上移开,滚动会立即停止 */
1
2
3
  1. 设置 overflow 设置外部 overflow 为 hidden,内容元素为 auto ,内部元素超出 body 即产生部分滚动,超出的部分 body 隐藏。
body {
    overflow-y: hidden;
}
.wrapper {
    overflow-y: auto;
}
1
2
3
4
5
6

# iOS 上拉边界下拉出现空白

在 iOS 中,手指按住屏幕上下拖动,会触发 touchmove 事件。这个事件触发的对象是整个 webview 容器,容器自然会被拖动,剩下的部分会成空白。

document.body.addEventListener('touchmove', (e) => {
      if (e._isScroller) return;
      e.preventDefault()
    }, {
      passive: false
    })
1
2
3
4
5
6
值得注意的是我们要过滤掉具有滚动容器的元素。
1

# 移动端click屏幕产生200-300 ms的点击延迟

为什么会产生 click 延时?

iOS 中的 safari,为了实现双击缩放操作,在单击 300ms 之后,如果未进行第二次点击,则执行 click 单击操作。也就是说来判断用户行为是否为双击产生的。但是,在 App 中,无论是否需要双击缩放这种行为,click 单击都会产生 300ms 延迟。

fastclick可以解决在手机上点击事件的300ms延迟

# iphoneX系列安全区域适配问题

具体操作为:viewport-fit meta 标签设置为 cover,获取所有区域填充。 判断设备是否属于 iPhone X,给头部底部增加适配层

增加适配层

使用 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);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

解决方法 (opens new window)

# 设置input 文本框的 placeholder 的颜色

input::-webkit-input-placeholder{
    color:rgba(144,147,153,1);
}
1
2
3

# 忽略自动识别

当页面上的内容包含了手机号/邮箱等,会自动转换成可点击的链接

<!-- 忽略浏览器自动识别数字为电话号码 -->
<meta name="format-detection" content="telephone=no">

<!-- 忽略浏览器自动识别邮箱账号 -->
<meta name="format-detection" content="email=no">
1
2
3
4
5

# 滑动穿透

当你想在出现遮罩的时候,锁住用户的滚动行为,你可以这么做。 html 结构如下

<div class="mask">
  <div class="content">我是弹框</div>
</div>
1
2
3

如果在vue中

<div class="mask" @touchumove.prevent></div>
1

如果.content也有滚动条,那么只要阻止遮罩本身就行

<div class="mask" @touchumove.self.prevent></div>
1

# H5,ios键盘唤起,键盘收起以后页面不归位

function blur(){
	let u = navigator.userAgent, app = navigator.appVersion;
    let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
    if(isIOS){
        setTimeout(() => {
          const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0
          window.scrollTo(0, Math.max(scrollHeight - 1, 0))
          }, 200)
      }
}
1
2
3
4
5
6
7
8
9
10

# IOS 下 fixed 失效的原因

软键盘唤起后,页面的 fixed 元素将失效,变成了 absolute,所以当页面超过一屏且滚动时,失效的 fixed 元素就会跟随滚动了。不仅限于 type=text 的输入框,凡是软键盘(比如时间日期选择、select 选择等等)被唤起,都会遇到同样地问题。

解决方法: 不让页面滚动,而是让主体部分自己滚动,主体部分高度设为 100%,overflow:scroll

<body>
  <div class='warper'>
    <div class='main'></div>
  <div>
  <div class="fix-bottom"></div>
</body>
1
2
3
4
5
6
.warper {
  position: absolute;
  width: 100%;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  overflow-y: scroll;
  -webkit-overflow-scrolling: touch; /* 解决ios滑动不流畅问题 */
}
.fix-bottom {
  position: fixed;
  bottom: 0;
  width: 100%;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 安卓弹出的键盘遮盖文本框

给input和textarea标签添加focus事件,如下,先判断是不是安卓手机下的操作,当然,可以不用判断机型,Document 对象属性和方法,setTimeout延时0.5秒,因为调用安卓键盘有一点迟钝,导致如果不延时处理的话,滚动就失效了

    changefocus(){
      let u = navigator.userAgent, app = navigator.appVersion;
      let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1;
      if(isAndroid){
        setTimeout(function() {
         document.activeElement.scrollIntoViewIfNeeded();
         document.activeElement.scrollIntoView();
        }, 500);       
      }
    },
1
2
3
4
5
6
7
8
9
10

# 回到顶部

利用 scrollIntoView ,让容器滚动到目标元素位置。

  • 「behavior」:动画过渡效果,默认auto无,可选smooth平滑
  • 「inline」:水平方向对齐方式,默认nearest就近对齐,可选start顶部对齐、center中间对齐和end底部对齐
  • 「block」:垂直方向对齐方式,默认start顶部对齐,可选center中间对齐、end底部对齐和nearest就近对齐
const gotopBtn = document.getElementById("gotop-btn");
openBtn.addEventListener("click", () => document.body.scrollIntoView({ behavior: "smooth" }));
1
2

# 简化懒性加载

利用 IntersectionObserver,它提供一种异步观察目标元素及其祖先元素或顶级文档视窗交叉状态的方法。 图片懒加载:图片进入可视区域就赋值加载图片,赋值完成还需对图片停止监听。

<img data-src="pig.jpg">
...


const imgs = document.querySelectorAll("img.lazyload");
const observer = new IntersectionObserver(nodes => {
    nodes.forEach(v => {
        if (v.isIntersecting) { // 判断是否进入可视区域
            v.target.src = v.target.dataset.src; // 赋值加载图片
            observer.unobserve(v.target); // 停止监听已加载的图片
        }
    });
});
imgs.forEach(v => observer.observe(v));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Last Updated: 12/30/2022, 2:33:12 PM