移动端开发问题集锦

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jplyue/article/details/82180904

一些常用的css初始化

//滚动条卡顿
body {
 -webkit-overflow-scrolling: touch;
 overflow-scrolling: touch;
}

//禁止选择文本
Element {
 -webkit-user-select: none;
 -moz-user-select: none;
 -khtml-user-select: none;
  user-select: none;
}

//长时间按住页面出现闪退
element {
 -webkit-touch-callout: none;
}

//iphone及ipad下输入框默认内阴影
Element{
 -webkit-appearance: none;
}

1px问题

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

变粗

原因:不同设备的dpr不同,同样的css 1px放在dpr为2的设备上,对应的物理像素为2px。

解决方案:

1. css方案,仅支持ios8以上

不推荐

.border { border: 1px solid #999 }
@media screen and (-webkit-min-device-pixel-ratio: 2) {
    .border { border: 0.5px solid #999 }
}
@media screen and (-webkit-min-device-pixel-ratio: 3) {
    .border { border: 0.333333px solid #999 }
}
2. border-image 麻烦、圆角问题
3. 渐变
@media screen and (-webkit-min-device-pixel-ratio: 2){
    .ui-border-t {
        background-position: left top;
        background-image: -webkit-gradient(linear,left bottom,left top,color-stop(0.5,transparent),color-stop(0.5,#e0e0e0),to(#e0e0e0));
    }
}

可以修改颜色,但是圆角问题无法解决。局限且麻烦

4. :before, :after与transform

构建1个伪元素, 将它的长宽放大到2倍, 边框宽度设置为1px, 再以transform缩放到50%.

.radius-border{
    position: relative;
}
@media screen and (-webkit-min-device-pixel-ratio: 2){
    .radius-border:before{
        content: "";
        pointer-events: none; /* 防止点击触发 */
        box-sizing: border-box;
        position: absolute;
        width: 200%;
        height: 200%;
        left: 0;
        top: 0;
        border-radius: 8px;
        border:1px solid #999;
        -webkit-transform(scale(0.5));
        -webkit-transform-origin: 0 0;
        transform(scale(0.5));
        transform-origin: 0 0;
    }
}

优点: 适用于不同的边框样式

缺点: 代码多, 占据了伪元素,

5. meta

针对不同dpr下的scale进行缩放, 比如dpr为2时

<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
if (!dpr && !scale) {
    var isAndroid = win.navigator.appVersion.match(/android/gi);
    var isIPhone = win.navigator.appVersion.match(/iphone/gi);
    var devicePixelRatio = win.devicePixelRatio;
    if (isIPhone) {
        // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
        if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
            dpr = 3;
        } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
            dpr = 2;
        } else {
            dpr = 1;
        }
    } else {
        // 其他设备下,仍旧使用1倍的方案
        dpr = 1;
    }
    scale = 1 / dpr;
}

缺点: 安卓对devicePixelRatio支持不好,也不一定会根据scale进行页面缩放

可以对安卓做检测, 如果是安卓, js动态加载css.

移动端点透问题

touch事件包括:touchstart touchmove touchend touchcancel

touchcancel是在取消touch时自动触发,非手动触发。

情景再现:有两个div1和div2,div1绝对定位在2的上面,理论上阻挡了所有的事件。但是当1的display设置为none的时候,2就被点击了。这就是点透。。。点击事件穿透了1到达了2。

点透发生的条件:

  1. A 和 B没有继承关系(涉及到冒泡)
  2. A发生touch, A touch后立即消失, B事件绑定click
  3. A z-index大于B,即A显示在B浮层之上

点透发生的原因:

手指触摸屏幕的时候,触发的顺序是:

点击一下
touchstart
touchend
click
tap
singleTap

touch结束后,1消失了,移动端的click事件还有300ms左右的延迟,所以触发click的时候发现点击元素变成了2,然后click事件就作用在了b上

如何解决?

在touchend结束的时候组织click事件的触发

    div1.addEventListener('touchend', function(e) {
      e.preventDefault();
    });

reference

猜你喜欢

转载自blog.csdn.net/jplyue/article/details/82180904