移动设备适配总结篇

353 阅读2分钟

背景

由于移动端设备繁多,Android和IOS浏览器规范不是完全一致,所以会有一些移动端适配的问题

1px高度

原因

对于750设计稿,相对于iphone6的屏幕宽度是375,即2倍的dpr,当在样式中写入border: 1px solid #ccc时,渲染出来的相当于1*2px的边框,所以会比设计图粗

解决方案

  • 伪元素
// 单条线
.box {
    position: relative;
    &::after {
        position: after;
        top: 0;
        left: 0;
        content: '';
        display: block;
        background-color: #e5e5e5;
        width: 100%;
        height: 1px;
        transform: scale(1,0.5);
    }
}

// 边框

.box {
    position: relative;
    &::after {
        position: after;
        top: 0;
        left: 0;
        content: '';
        display: block;
        width: 200%;
        height: 200%;
        transform: scale(0.5);
        transform-origin: left top;
        border: 1px solid #E5E5E5;
        box-sizing: border-box;
    }
}

  • viewport + rem
          var viewport = document.querySelector("meta[name=viewport]");
          //下面是根据设备像素设置viewport
          if (window.devicePixelRatio == 1) {
              viewport.setAttribute('content', 'width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no');
          }
          if (window.devicePixelRatio == 2) {
              viewport.setAttribute('content', 'width=device-width,initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no');
          }
          if (window.devicePixelRatio == 3) {
              viewport.setAttribute('content', 'width=device-width,initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no');
          }
          var docEl = document.documentElement;
          var fontsize = 32* (docEl.clientWidth / 750) + 'px';
          docEl.style.fontSize = fontsize;

  • flexible 阿里的flexible,相当于hack了vw,vh

300毫秒延迟和点击穿透

原因

由于移动端会有双击缩放的这个操作,因此浏览器在click之后要等待300ms,看用户有没有下一次点击

解决方案

  • 禁用缩放,相当于不需要再等待300毫秒
<meta name="viewport" content="user-scalable=no">
<meta name="viewport" content="initial-scale=1,maximum-scale=1">
  • touchaction: 当触控事件发生在元素上时,不进行任何操作。不过可能有额外的副作用,不推荐
touch-action作为html标签的属性。
  • FastClick 检测到touchend事件的时候,会通过DOM自定义事件立即出发模拟一个click事件,并把浏览器在300ms之后的click事件阻止掉

rem和vw,vh

现在相比rem,vw,vh方案已经渐渐的占据了主流,但是少数机型还是不支持,ie11不支持 少数低版本手机系统 ios8、android4.4以下不支持

  • vw,vh 可以使用postcss-px-to-viewport插件,可以对px进行转换
{
    loader: 'postcss-loader',
    options: {
    	plugins: ()=>[
        	require('autoprefixer')({
        		browsers: ['last 5 versions']
        	}),
        	require('postcss-px-to-viewport')({
        		viewportWidth: 375,
        		viewportHeight: 1334,
        		unitPrecision: 3,
        		viewportUnit: 'vw',
        		selectorBlackList: ['.ignore', '.hairlines'],
                minPixelValue: 1,
                mediaQuery: false
        	})
    	]
}

  • rem 动态设置Html元素的font-size,元素使用单位rem,相对根元素的font-size动态设置
<script type="text/javascript">
    (function() {
        var deviceWidth = document.documentElement.clientWidth;
        deviceWidth = deviceWidth < 320 ? 320 : deviceWidth > 640 ? 640 : deviceWidth;
        document.documentElement.style.fontSize = deviceWidth / 7.5 + 'px';
    })();
</script>