你的位置:首页 > Java教程

[Java教程]js动态计算移动端rem


    在做移动端web app的时候,众所周知,移动设备分辨率五花八门,虽然我们可以通过CSS3的media query来实现适配,例如下面这样:

 1 html { 2     font-size : 20px; 3   } 4   @media only screen and (min-width: 401px){ 5     html { 6       font-size: 25px !important; 7     } 8   } 9   @media only screen and (min-width: 428px){10     html {11       font-size: 26.75px !important;12     }13   }14   @media only screen and (min-width: 481px){15     html {16       font-size: 30px !important; 17     }18   }19   @media only screen and (min-width: 569px){20     html {21       font-size: 35px !important; 22     }23   }24   @media only screen and (min-width: 641px){25     html {26       font-size: 40px !important; 27     }28   }

 但是这种做法并不能适配所有设备,于是就有了实现全适配的JS解决方案,例如下面这样:

 1 ;(function (doc, win, undefined) { 2      var docEl = doc.documentElement, 3       resizeEvt = 'orientationchange' in win? 'orientationchange' : 'resize', 4       recalc = function () { 5        var clientWidth = docEl.clientWidth; 6        if (clientWidth === undefined) return; 7        docEl.style.fontSize = 20 * (clientWidth / 320) + 'px'; 8       }; 9      if (doc.addEventListener === undefined) return;10      win.addEventListener(resizeEvt, recalc, false);11      doc.addEventListener('DOMContentLoaded', recalc, false)12     })(document, window);13    

另外附上淘宝移动端适配解决方案flexible.js源码:

 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     //将根据已有的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 devicePixelRatio = win.devicePixelRatio; 38     if (isIPhone) { 39       // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案 40       if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {         41         dpr = 3; 42       } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ 43         dpr = 2; 44       } else { 45         dpr = 1; 46       } 47     } else { 48       // 其他设备下,仍旧使用1倍的方案 49       dpr = 1; 50     } 51     scale = 1 / dpr; 52   } 53  54   docEl.setAttribute('data-dpr', dpr); 55   if (!metaEl) { 56     metaEl = doc.createElement('meta'); 57     metaEl.setAttribute('name', 'viewport'); 58     metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); 59     if (docEl.firstElementChild) { 60       docEl.firstElementChild.appendChild(metaEl); 61     } else { 62       var wrap = doc.createElement('div'); 63       wrap.appendChild(metaEl); 64       doc.write(wrap.innerHTML); 65     } 66   } 67  68   function refreshRem(){ 69     var width = docEl.getBoundingClientRect().width; 70     if (width / dpr > 540) { 71       width = 540 * dpr; 72     } 73     var rem = width / 10; 74     docEl.style.fontSize = rem + 'px'; 75     flexible.rem = win.rem = rem; 76   } 77  78   win.addEventListener('resize', function() { 79     clearTimeout(tid); 80     tid = setTimeout(refreshRem, 300); 81   }, false); 82   win.addEventListener('pageshow', function(e) { 83     if (e.persisted) { 84       clearTimeout(tid); 85       tid = setTimeout(refreshRem, 300); 86     } 87   }, false); 88  89   if (doc.readyState === 'complete') { 90     doc.body.style.fontSize = 12 * dpr + 'px'; 91   } else { 92     doc.addEventListener('DOMContentLoaded', function(e) { 93       doc.body.style.fontSize = 12 * dpr + 'px'; 94     }, false); 95   } 96    97  98   refreshRem(); 99 100   flexible.dpr = win.dpr = dpr;101   flexible.refreshRem = refreshRem;102   flexible.rem2px = function(d) {103     var val = parseFloat(d) * this.rem;104     if (typeof d === 'string' && d.match(/rem$/)) {105       val += 'px';106     }107     return val;108   }109   flexible.px2rem = function(d) {110     var val = parseFloat(d) / this.rem;111     if (typeof d === 'string' && d.match(/px$/)) {112       val += 'rem';113     }114     return val;115   }116 117 })(window, window['lib'] || (window['lib'] = {}));

flexible.js