手机布局rem的使用(rem)

最后一堆代码是举例的全码.

一 直接<head>标签里套用以下,其他都不用

1 <script>
2         document.documentElement.style.fontSize = document.documentElement.clientWidth / 750*100 + "px";
3         window.addEventListener("resize",function(){
4             document.documentElement.style.fontSize = document.documentElement.clientWidth / 750*100 + "px";
5         },false);
6 </script>

早就听说布局总共约4种:

  静态布局 , 流式布局 , 响应式布局 , 自适应布局(以下是解释和区别 , 不敢保证正确 , 但个人认同)

静态布局:

    根据固定宽度, 完成布局,在屏幕的分辨率不同 , 显示也不同; 

流式布局: 

    当浏览器宽度小于多少时怎么显示布局 ;当浏览器宽度大于多少时, 怎么显示布局 ; 展示的方向像水流一样,一部分一部分的加载 ,额不知道花瓣网是不是就算;

响应式和自适应的共同点: 

    都是自动检测设备, 根据设备的不同 ,自动采用不同的css ,而且css都是采用的百分比等单位 ,而不是固定的宽度单位; 

响应式和自适应的不同点: 

    在不同设备上看上去不同;

    响应式会随设备的改变而响应改变布局的样式;

    自适应是在所有设备上看都是固定的样式 ,好像采用一个模板一样; 

二 参考

本篇有大部分摘抄大神的http://www.cnblogs.com/mufc-go/p/4625115.html  ,谢谢无偿分享 . 

代码有更新,最好直接查看github

github:https://github.com/finance-sh/adaptive

adaptivejs利用rem解决移动端页面开发的自适应问题

页面模板初始化的时候不用设置viewport标签,由js生成。

我们在head标签的顶部引入js,按以下方法使用即可

adaptivejs原理:

利用rem布局,根据公式  

html元素字体大小 = document根节点(html)宽度 * 100 / 设计图宽度  

计算html元素的font-size,使1rem等于100px,方便快速开发  
开发时,一个div设计图宽度为89px,那么在css中我们可以这样书写:0.89rem;  
如果是文字,我们也建议使用rem 

对于iphone的retina高清显示屏,基本版本(adaptive.js)我们做了缩放处理,以达到最佳显示效果。 对于快速开发版本(adaptive-version2.js),viewport的width等于设备宽度,不会缩放 
以下是
adaptivejs 
var adaptive = {};
(function (win, lib) {
    var doc = win.document;
    var docEl = doc.documentElement;
    // 设备像素比
    var devicePixelRatio = win.devicePixelRatio;
    // 我们设置的布局视口与理想视口的像素比
    var dpr = 1; 
    // viewport缩放值
    var scale = 1; 
    // 设置viewport
    function setViewport() {
        // 判断IOS
        var isIPhone = /iphone/gi.test(win.navigator.appVersion);
        if (lib.scaleType === 2 && isIPhone || lib.scaleType === 3) {
            dpr = devicePixelRatio;
        }
        // window对象上增加一个属性,提供对外的布局视口与理想视口的值
        win.devicePixelRatioValue = dpr;
        // viewport缩放值,布局视口缩放后刚好显示成理想视口的宽度,页面就不会过长或过短了
        scale = 1 / dpr;
        // 获取已有的viewport
        var hasMetaEl = doc.querySelector('meta[name="viewport"]');
        var metaStr = 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no';
        if (dpr === 1) {
            metaStr = 'width=device-width, '.concat(metaStr);
        }
        if (!isIPhone && dpr !== 1) {
            metaStr = metaStr.concat(', target-densitydpi=device-dpi');
        }
        // 如果有,改变之
        if (hasMetaEl) {
            hasMetaEl.setAttribute('content', metaStr);
        }
        // 如果没有,添加之
        else {
            var metaEl = doc.createElement('meta');
            metaEl.setAttribute('name', 'viewport');
            metaEl.setAttribute('content', metaStr);
            
            if (docEl.firstElementChild) {
                docEl.firstElementChild.appendChild(metaEl);
            }
            else {
                var containDiv = doc.createElement('div');
                containDiv.appendChild(metaEl);
                docEl.appendChild(containDiv);
            }
        }
    }
    
    var newBase = 100;
    lib.errDpr = 1;

    function setRem() {
        // 布局视口
        // var layoutView = docEl.clientWidth; 也可以 获取布局视口的宽度
        var layoutView;
        if (lib.maxWidth) {
            layoutView = Math.min(docEl.getBoundingClientRect().width, lib.maxWidth * dpr);
        }
        else {
            layoutView = docEl.getBoundingClientRect().width;
        }
        // 为了计算方便,我们规定 1rem === 100px设计图像素,我们切图的时候就能快速转换
        // 有人问,为什么不让1rem === 1px设计像素呢?
        // 设计图一般是640或者750px
        // 布局视口一般是320到1440
        // 计算一个值,使layout的总宽度为 (desinWidth/100) rem
        // 那么有计算公式:layoutView / newBase = desinWidth / 100
        // newBase = 100 * layoutView / desinWidth
        // newBase = 介于50到200之间
        // 如果 1rem === 1px 设计像素,newBase就介于0.5到2之间,由于很多浏览器有最小12px限制,这个时候就不能自适应了
        newBase = 100 * layoutView / lib.desinWidth * (lib.errDpr || 1);
        docEl.style.fontSize = newBase + 'px';
        // rem基准值改变后,手动reflow一下,避免旋转手机后页面自适应问题
        doc.body&&(doc.body.style.fontSize = lib.baseFont / 100 + 'rem');
        // 重新设置rem后的回调方法
        lib.setRemCallback&&lib.setRemCallback();
        lib.newBase = newBase;
    }
    var tid;
    lib.desinWidth = 750;
    lib.baseFont = 28;
    // 局部刷新的时候部分chrome版本字体过大的问题
    lib.reflow = function() {
        docEl.clientWidth;
    };
    // 检查安卓下rem值是否显示正确
    function checkRem() {
        if (/android/ig.test(win.navigator.appVersion)) {
            var hideDiv = document.createElement('p');
            hideDiv.style.height = '1px';
            hideDiv.style.width = '2.5rem';
            hideDiv.style.visibility = 'hidden';
            document.body.appendChild(hideDiv);
            var now = hideDiv.offsetWidth;
            var right = lib.newBase * 2.5; 
            if (Math.abs(right / now - 1) > 0.05) {
                lib.errDpr = right / now;
                setRem();
            }
            document.body.removeChild(hideDiv);
        }
    }
    lib.init = function () {
        // resize的时候重新设置rem基准值
        // 触发orientationchange 事件时也会触发resize,故不需要再添加此事件了
        win.addEventListener('resize', function () {
            clearTimeout(tid);
            tid = setTimeout(setRem, 300);
        }, false);
        // 浏览器缓存中读取时也需要重新设置rem基准值
        win.addEventListener('pageshow', function (e) {
            if (e.persisted) {
                clearTimeout(tid);
                tid = setTimeout(setRem, 300);
            }
        }, false);
        // 设置body上的字体大小
        if (doc.readyState === 'complete') {
            doc.body.style.fontSize = lib.baseFont / 100 + 'rem';
            checkRem();
        }
        else {
            doc.addEventListener('DOMContentLoaded', function (e) {
                doc.body.style.fontSize = lib.baseFont / 100 + 'rem';
                checkRem();
            }, false);
        }
        setViewport();
        // 设置rem值
        setRem();
        // html节点设置布局视口与理想视口的像素比
        docEl.setAttribute('data-dpr', dpr);
    };
    // 有些html元素只能以px为单位,所以需要提供一个接口,把rem单位换算成px
    lib.remToPx = function (remValue) {
        return remValue * newBase;
    };
})(window, adaptive);
if (typeof module != 'undefined' && module.exports) {
    module.exports = adaptive;
} else if (typeof define == 'function' && define.amd) {
    define(function() {
        return adaptive;
    });
} else {
    window.adaptive = adaptive;
}
View Code

注意:如果设计图宽度大于document的宽度,0.01rem将小于1px,故如果设计图是1px,在css中仍然用1px显示。

可用的全局变量:window.devicePixelRatioValue 当前页面设置的设备像素比

优化宽度问题

新增最大宽度,解决平板或手机横屏时体验不佳的问题

window['adaptive'].maxWidth = 480; // 设置最大宽度,默认540px

需要css配合使用,添加如下代码:

body {
    max- 6.4rem; // 设计图宽度为640px时为6.4rem ,750时为7.5rem ,以此类推
    margin: 0 auto;
}
body * {
    max- 6.4rem; // 设计图宽度为640px时为6.4rem ,750时为7.5rem ,以此类推
}
// 设计图宽度
    window['adaptive'].desinWidth = 640;
    // body 字体大小 会将body字体大小设置为 baseFont / 100 + 'rem'  750的设计图一般设置为28,640的设计图一般设置为24
    window['adaptive'].baseFont = 24;
    /*
    // 显示最大宽度 可选
    window['adaptive'].maxWidth = 480;
    // rem值改变后执行方法 可选
    window['adaptive'].setRemCallback = function () {
        alert(1)
    }
    // scaleType 1:iphone andriod下viewport均无缩放 2:iphone下viewport有缩放,andriod没有 3:iphone andriod下viewport均有缩放; 默认值为1
    window['adaptive'].scaleType = 1;
    */
    // 初始化
    window['adaptive'].init();
 项目html
  1 <!DOCTYPE html>
  2 <html>
  3     <head>
  4         <meta charset="UTF-8">
  5         <meta content="yes" name="apple-mobile-web-app-capable">
  6         <meta content="no" name="apple-touch-fullscreen">
  7         <meta content="telephone=no,email=no" name="format-detection">
  8         <meta name="App-Config" content="fullscreen=yes,useHistoryState=yes,transition=yes">
  9         <meta name="viewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
 10         <link rel="stylesheet" type="text/css" href="css/common.css"/>
 11         <link rel="stylesheet" type="text/css" href="css/yunxian.css"/>
 12         <script src="js/jquery-1.10.1.min.js"></script>
 13         <script src="js/adaptive.js"></script>
 14         <script src="js/yunxian.js"></script>
 15         <script>
 16             window['adaptive'].desinWidth = 750;
 17             window['adaptive'].baseFont = 28;
 18             window['adaptive'].maxWidth = 480;
 19             window['adaptive'].scaleType = 2;
 20             window['adaptive'].init();
 21            </script>
 22         <title>车险</title>
 23     </head>
 24     <body>
 25         <form action="" method="post">
 26             <div class="yx1">
 27                 <div class="yx1_menu">
 28                     选择行驶证类型
 29                 </div>
 30                 <div class="yx1_con">
 31                     <span>
 32                         <img id="checkimg1" src="img/chose1.png"/>&nbsp; 个人
 33                     </span>
 34                     <span>
 35                         <img id="checkimg2" src="img/chose2.png"/>&nbsp; 企业
 36                     </span>
 37                 </div>
 38             </div>
 39             <div class="yx_personal">
 40                 <div class="yx_pl">
 41                 </div>
 42                 <div class="yx_pr">
 43                     <div class="yx_prcon1">
 44                         投保人 <input type="text" placeholder=" 公司名称或姓名"  />
 45                     </div>
 46                     <div class="yx_prcon1">
 47                         身份证号 <input class="idnummer" type="text" placeholder=" 机构请填写组织机构代码证"  />
 48                     </div>
 49                     <div class="yx_prcon1" style="border:none ;">
 50                         地址 <input type="text" placeholder=" "  />
 51                     </div>
 52                 </div>
 53             </div>
 54             <div class="yx_car">
 55                 <div class="yx_cl">
 56                 </div>
 57                 <div class="yx_cr">
 58                     <div class="yx_crcon1">
 59                         <span class="menu_safe">是否首次投保 </span>
 60                         <div class="yx_crcon11">
 61                             <span>
 62                                 <img id="yx_crcon_yes" src="img/chose1.png"/>&nbsp; 63                             </span>
 64                             <span>
 65                                 <img id="yx_crcon_no" src="img/chose2.png"/>&nbsp; 66                             </span>
 67                         </div>
 68                     </div>
 69                     <div class="yx_crcon1">
 70                         车牌号码 <input type="text"/>
 71                     </div>
 72                     <div class="yx_crcon1">
 73                         所有人/车主 <input type="text" class="yx_input3"/>
 74                     </div>
 75                     <div class="yx_crcon1">
 76                         品牌型号 <input type="text"/>
 77                     </div>
 78                     <div class="yx_crcon1">
 79                         发动机型号 <input type="text"/>
 80                     </div>
 81                     <div class="yx_crcon1">
 82                         车辆识别代码/VIN码/车架号 <input type="text" class="yx_input6"/>
 83                     </div>
 84                     <div class="yx_crcon1">
 85                         注册日期/初等日期 <input type="text" class="yx_input7"/>
 86                     </div>
 87                     <div class="yx_crcon1">
 88                         核定载人数 <input type="text" placeholder="   输入货物数量    如:20吨 "  />
 89                     </div>
 90                     <div class="yx_crcon1" style="border:none ;">
 91                         核定载质量/整备质量 <input type="text" class="yx_input9"/>
 92                     </div>
 93                 </div>
 94             </div>
 95             <div class="yx_safemenu">
 96                 <div class="yx_safemenul">
 97                 </div>
 98                 <div class="yx_safemenur">
 99                     <div class="yx_safemenucon">
100                         投保险种 <a href="">
101                             <input type="text" class="more" value=" XXXXXDDDDDDDD"/>
102                         </a>
103                     </div>
104                 </div>
105             </div>
106             <div class="information">
107                 <div class="load">
108                     <img src="img/idcard1.png"/>
109                     <div></div>
110                 </div>
111                 <div class="load">
112                     <img src="img/idcard2.png"/>
113                     <div></div>
114                 </div>
115                 <div class="load">
116                     <img src="img/companycard.png"/>
117                     <div></div>
118                 </div>
119                 <div class="load">
120                     <img src="img/carcard.png"/>
121                     <div></div>
122                 </div>
123             </div>
124             <div class="deal">
125                 <input type="checkbox" />
126                 &nbsp; 我已阅读并同意<a href="">《人保保险投保须知》</a>
127             </div>
128             <div class="submit">
129                 <input type="submit" value="提交资料"/>
130             </div>
131         </form>
132     </body>
133 </html>
View Code
 
原文地址:https://www.cnblogs.com/wangduojing/p/6841186.html