# 其它

# 判断是否为Retina屏

if (window.devicePixelRatio && window.devicePixelRatio >= 2)
1

# click延时的问题

现象: 监听元素click事件,实际触发延时200ms

原因:

  • 移动端双击默认会放大,在第一次点击后需等待200ms左右来判断是否会进行下次点击
  • 事件冒泡:touchstart -> touchmove -> touchend -> click

解决方式:

  • ① 禁用缩放:
    • 缺点:不支持缩放
  <meta name="viewport" content="user-scalable=no">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1">
1
2
  • ② 用touchstart替代click

    • 优点:解决了 延时、点透 事件
    • 缺点:具有滚动(touchmove)情况,还是需要使用click
  • ③ 判定touchend - touchstart:监听touchstart事件touchend事件之间的移动距离、时间差。若很短,则主动进行click事件,并阻止touchend的默认行为。

  • ④ 利用 Zepto.js 中的tap事件代替

    • 原理:Zepto会给document绑定一系列touch事件来实现自定义tab。当touchend回调触发时,代表一次点击结束。所以不会出现延迟。
    • 缺点:会发生点透事件

# “点透事件”

原理:因为Zepto.js的tap事件是通过touch事件模拟的,故tap要冒泡到document才触发

原因:

  • 有两层A、B(A盖在上面)
  • touchstart 阶段就隐藏了A;
  • click 被触发时,能够使下面的B“被点击”
  • touchstart -> touchmove -> touchend -> click

解决办法:为元素绑定touchend事件,并在内部加上e.preventDefault(),从而阻止click事件的产生

# a标签点击出现灰色背景

解决:

  • 1、IOS和部分安卓
    .child {
        -webkit-tab-highlight-color: rgba(0, 0, 0, 0);
    }
    
    1
    2
    3
  • 2、部分安卓、winphone
    <meta name="msapplication-tap-highlight" content="no">
    
    1
  • 3、小米2 使用div标签

# 两端在事件对象上的区别(TouchEvent、Touch、TouchList)

对于TouchEvent(触摸事件对象),它会比MouseEvent(鼠标事件对象)多出一些属性值:

  • touches
    • 当前屏幕上,所有Touch对象的列表
  • targetTouches
    • 当前对象上,所有Touch对象的列表
  • changedTouches
    • 涉及当前事件的,所有Touch对象的列表

同时,与MouseEvent中有关位置/目标的属性:clientXclientYpageXpageYscreenXscreenYtarget会放到Touch对象中。

# 滚动性能优化

因为一般事件处理函数(耗时)会比默认行为先执行。对于滚动事件,也是一样。所以看上去可能会出现一些卡顿。

解决方法:Passive event listeners(被动事件监听器)

elem.addEventListener('touchstart', fn, { passive: false })
1

通过给第三个参数传递passivefalse(被动为假,即主动。)来明确告诉浏览器:事件处理程序自己会调用preventDefault来阻止默认行为,你不用等了。

如果能提前告诉浏览器:“我不调用preventDefault来阻止默认行为”,那么浏览器就能快速生成事件,从而提升页面性能。

# 常用媒体查询兼容方案

查看

# ios、安卓6及以上机型无法播放视频

const doPreview = (index) => {
    // ios、安卓6及以上机型无法播放视频
    // hack做法:手动触发播放、暂停。
    if (Env.isIos() || (Env.isAndroid() && Env.getAndroidVersion() >= 6)) {
        audioRef.current.doPlay(index);
        audioRef.current.doPause(index);
    }
};
1
2
3
4
5
6
7
8
<AudioComponent ref={audioRef} />
1

# 禁用微信调整字体大小

(function disableWeixinTextAdjust() {
    function handleFontSize() {
        const WeixinJSBridge = window.WeixinJSBridge;
        WeixinJSBridge.invoke('setFontSizeCallback', { fontSize: 0 });
        WeixinJSBridge.on('menu:setfont', () => {
            WeixinJSBridge.invoke('setFontSizeCallback', { fontSize: 0 });
        });
    }

    if (typeof window.WeixinJSBridge === 'object'
        && typeof window.WeixinJSBridge.invoke === 'function') {
        handleFontSize();
    } else if (document.addEventListener) {
        document.addEventListener('WeixinJSBridgeReady', handleFontSize, false);
    } else if (document.attachEvent) {
        document.attachEvent('WeixinJSBridgeReady', handleFontSize);
        document.attachEvent('onWeixinJSBridgeReady', handleFontSize);
    }
}());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 文本字号不建议使用rem

  • 不希望文本在 Retina屏幕 下变小
  • 希望在大屏手机上看到更多文本
  • 不希望出现13px和15px这样的奇葩尺寸

综上,考虑文本还是使用px作为单位

只不过使用[data-dpr]属性来 区分不同dpr下的文本字号大小(依旧使用 px)。

div {
    width: 1rem; 
    height: 0.4rem;
    font-size: 12px; /* 默认写上dpr为1的fontSize */
}
[data-dpr="2"] div {
    font-size: 24px;
}
[data-dpr="3"] div {
    font-size: 36px;
}
1
2
3
4
5
6
7
8
9
10
11

# 移动端active伪类无效

// // 点击时透明为 0.8
// .u-submit:active {
//     opacity: 0.8;
// }

// 添加 onTouchStart 事件即可(可为空函数)
<div onTouchStart className="u-submit">提交</div>
1
2
3
4
5
6
7

# position: fixed在iOS滑动不固定

范围: 部分iOS机型(目前发现 iOS <= 13.6

在 “滚动容器” 内,子元素使用了 position: fixed ,出现滑动不固定。

# 解决

  • 法一:在使用了 position: fixed 元素上加上 transform: translateZ(0)
  • 法二:将fixed元素移出 滚动容器 外

# Android下line-height文字垂直居中偏移问题

在移动端开发,Android的单行文字无法在容器中垂直居中。

常见于一些 tag 和 按钮

问题根源:设定同一font-size的文字,在不同字体里的高度是不一样的

# 调研

  • 所有 “内联元素” 都有两个高度:content-area(基于字体度量)、virtual-area(有效高度,即line-height)
  • content-area在内部渲染时已经发生偏移,而css的居中方案只会控制整个content-area的居中
  • line-height: normal是基于字体度量计算出来的

# 分析

需要针对content-areavirtual-area两类高度进行垂直居中。

# 解决方案

针对content-area的居中(二选一):

  • 方案1:line-height: normal
  • 方案2:设置<html lang="zh-cmn-Hans">font-family: sans-sarif(sans-sarif表示黑体)

针对virtual-area的居中(二选一):

  • 方案1:父容器position: relative,子元素position: absolute; left: 50%; top: 50%; transtorm: translate(-50%, -50%);
  • 方案2:父容器声明为Flex容器,并align-items: center

# iOS唤起数字键盘

<input pattern="[0-9]*">
1

另外,iOS会出现两次减号,会默认合并成一个字符。可改成数字键盘

# 参考

更新时间: 11/21/2021, 2:45:24 AM