移动端适配方案

前言

在移动端web开发上,不免会遇到各种移动设备的适配问题。在不断踩坑的路上,总结出了两套毕竟适合的适配移动端布局的方案。

方案一:媒体查询+viewport

描述:CSS3的媒体查询方案很大层度上已经帮我们完成了适配各种屏幕分辨率的问题。

 1 @charset "utf-8";
 2 html,body{
 3     width: 100%;
 4     height: 100%;
 5 }
 6 @media screen and (min- 320px) {
 7     html {
 8         font-size: 50px;
 9     }
10 }
11 @media screen and (min- 360px) {
12     html {
13         font-size: 56px;
14     }
15 }
16 
17 @media screen and (min- 400px) {
18     html {
19         font-size: 63px;
20     }
21 }
22 
23 @media screen and (min- 440px) {
24     html {
25         font-size: 69px;
26     }
27 }
28 
29 @media screen and (min- 480px) {
30     html {
31         font-size: 75px;
32     }
33 }
34 @media screen and (min- 640px) {
35     html {
36         font-size: 100px;
37     }
38 }
39 body{
40     font-family:'Microsoft YaHei',"Trebuchet MS",Verdana,Helvetica,Arial,sans-serif;
41     font-size:0.28rem;
42     color:#000000;
43     background-color: #ffffff;
44 }
45 *{
46     padding:0;
47     margin:0;
48     box-sizing: border-box;
49 }
50 ul,ol,ul li,ol li{
51     list-style-type: none;
52 }
53 /*设置取消input默认样式*/
54 input{
55     -webkit-appearance: none;
56     -moz-appearance: none;
57     appearance: none;
58 }
59 /*设置input placeholder字体色号*/
60 ::-webkit-input-placeholder {
61     color: #767676;
62 }
63 :-moz-placeholder {
64     color: #767676;
65 }
66 ::-moz-placeholder {
67     color: #767676;
68 }
69 :-ms-input-placeholder {
70     color: #767676;
71 }
72 input:focus::-webkit-input-placeholder{
73     color:#767676;
74 }
75 /*设置清除浮动*/
76 .clear:after{
77     content: '';
78     display: block;
79     width:100%;
80     height: 0;
81     visibility: hidden;
82     clear: both;
83 }
View Code

再结合针对移动网页优化的viewport,即可完成大部分的移动端适配布局。

<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
View Code
方案二:引入flexible

借鉴淘宝弹性布局方案flexible.js,即可完成移动端的布局。

代码出处:https://github.com/amfe/lib-flexible/blob/master/src/flexible.js

备注:直接引用时需要加js代码放置head头部内。

  1 ;(function(win, lib) {
  2     var doc = win.document;
  3     var docEl = doc.documentElement;
  4     var metaEl = doc.querySelector('meta[name="viewport"]');
  5     var flexibleEl = doc.querySelector('meta[name="flexible"]');
  6     var dpr = 0;
  7     var scale = 0;
  8     var tid;
  9     var flexible = lib.flexible || (lib.flexible = {});
 10     
 11     if (metaEl) {
 12         console.warn('将根据已有的meta标签来设置缩放比例');
 13         var match = metaEl.getAttribute('content').match(/initial-scale=([d.]+)/);
 14         if (match) {
 15             scale = parseFloat(match[1]);
 16             dpr = parseInt(1 / scale);
 17         }
 18     } else if (flexibleEl) {
 19         var content = flexibleEl.getAttribute('content');
 20         if (content) {
 21             var initialDpr = content.match(/initial-dpr=([d.]+)/);
 22             var maximumDpr = content.match(/maximum-dpr=([d.]+)/);
 23             if (initialDpr) {
 24                 dpr = parseFloat(initialDpr[1]);
 25                 scale = parseFloat((1 / dpr).toFixed(2));    
 26             }
 27             if (maximumDpr) {
 28                 dpr = parseFloat(maximumDpr[1]);
 29                 scale = parseFloat((1 / dpr).toFixed(2));    
 30             }
 31         }
 32     }
 33 
 34     if (!dpr && !scale) {
 35         var isAndroid = win.navigator.appVersion.match(/android/gi);
 36         var isIPhone = win.navigator.appVersion.match(/iphone/gi);
 37         var isIPad = win.navigator.appVersion.match(/ipad/gi);
 38         var devicePixelRatio = win.devicePixelRatio;
 39         if (isIPhone) {
 40             // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
 41             if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
 42                 dpr = 3;
 43             } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
 44                 dpr = 2;
 45             } else {
 46                 dpr = 1;
 47             }
 48         } else {
 49             // 其他设备下,仍旧使用1倍的方案
 50             dpr = 2;
 51         }
 52         scale = 1 / dpr;
 53     }
 54 
 55     docEl.setAttribute('data-dpr', dpr);
 56     if (!metaEl) {
 57         metaEl = doc.createElement('meta');
 58         metaEl.setAttribute('name', 'viewport');
 59         metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
 60         if (docEl.firstElementChild) {
 61             docEl.firstElementChild.appendChild(metaEl);
 62         } else {
 63             var wrap = doc.createElement('div');
 64             wrap.appendChild(metaEl);
 65             doc.write(wrap.innerHTML);
 66         }
 67     }
 68     function IsPC() 
 69     { 
 70         var userAgentInfo = navigator.userAgent; 
 71         var Agents = new Array("Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"); 
 72         var flag = true; 
 73         for (var v = 0; v < Agents.length; v++) { 
 74         if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = false; break; } 
 75         } 
 76         return flag; 
 77     }
 78     function refreshRem(){
 79         var width = docEl.getBoundingClientRect().width;
 80         // if (width / dpr> 540) {
 81         //     width = 540 * dpr;
 82         // }
 83         if (IsPC() && width < 2047) {
 84             width = 540;
 85         }
 86 
 87         var rem = width / 6.4;
 88         docEl.style.fontSize = rem + 'px';
 89         flexible.rem = win.rem = rem;
 90     }
 91 
 92     win.addEventListener('resize', function() {
 93         clearTimeout(tid);
 94         tid = setTimeout(refreshRem, 300);
 95     }, false);
 96     win.addEventListener('pageshow', function(e) {
 97         if (e.persisted) {
 98             clearTimeout(tid);
 99             tid = setTimeout(refreshRem, 300);
100         }
101     }, false);
102 
103     if (doc.readyState === 'complete') {
104         doc.body.style.fontSize = 14 * dpr + 'px';
105     } else {
106         doc.addEventListener('DOMContentLoaded', function(e) {
107             doc.body.style.fontSize = 14 * dpr + 'px';
108         }, false);
109     }
110     
111 
112     refreshRem();
113 
114     flexible.dpr = win.dpr = dpr;
115     flexible.refreshRem = refreshRem;
116     flexible.rem2px = function(d) {
117         var val = parseFloat(d) * this.rem;
118         if (typeof d === 'string' && d.match(/rem$/)) {
119             val += 'px';
120         }
121         return val;
122     }
123     flexible.px2rem = function(d) {
124         var val = parseFloat(d) / this.rem;
125         if (typeof d === 'string' && d.match(/px$/)) {
126             val += 'rem';
127         }
128         return val;
129     }
130 })(window, window['lib'] || (window['lib'] = {}));
View Code

加载完毕后,页面根节点html会有个data-dpr属性(dpr:设备像素和CSS像素的比值)。通过

[data-dpr=‘x’]属性设置CSS样式就可以很好的解决了在高清屏幕下图片存在失真的问题。

总结

通过这两种方案,就可以很好的解决了移动端适配的问题。当然推荐引入flexible.js。

作者:PC.aaron

出处:http://www.cnblogs.com/aaron-pan/

GitHub:https://github.com/PCAaron/PCAaron.github.io,欢迎star,获取最新内容

前端美食汇

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文地址:https://www.cnblogs.com/aaron-pan/p/6772754.html