移动端页面自适应解决方案:rem布局篇(代码片段)

sphmomo sphmomo     2023-03-16     430

关键词:

友情提示:想要更好的理解这篇文章,建议先读一下viewport深入理解
,了解一下视口。

假设我们的设计稿尺寸为750 * 1340。html5设计稿尺寸以及前端与设计之间协作流程一般分为下面两种。

方法一

引入:页面开头处引入下面这段代码,用于动态计算font-size

(function(doc, win) 
    var docEl = doc.documentElement,
        isIOS = navigator.userAgent.match(/(i[^;]+;( U;)? CPU.+Mac OS X/),
        dpr = isIOS ? Math.min(win.devicePixelRatio, 3) : 1,
        dpr = window.top === window.self ? dpr : 1, //被iframe引用时,禁止缩放
        scale = 1 / dpr,
        resizeEvt = ‘orientationchange‘ in window ? ‘orientationchange‘ : ‘resize‘;
    docEl.dataset.dpr = dpr;
    var metaEl = doc.querySelector("meta[name=‘viewport‘]");
    metaEl.content = ‘width=device-width,initial-scale=‘ + scale + ‘,maximum-scale=‘ + scale + ‘, minimum-scale=‘ + scale;

    var recalc = function() 
        var width = docEl.clientWidth;
        if (width / dpr > 750) //750为设计稿的宽度,此处应根据实际情况改变
            width = 750 * dpr;
        
        // 乘以100,px : rem = 100 : 1
        docEl.style.fontSize = 100 * (width / 750) + ‘px‘;
    ;

    if (!doc.addEventListener) return;
    win.addEventListener(resizeEvt, recalc, false);
    doc.addEventListener(‘DOMContentLoaded‘, recalc, false);
)(document, window);

//或者
(function(doc, win) 
    var docEl = doc.documentElement,
        resizeEvt = ‘orientationchange‘ in window ? ‘orientationchange‘ : ‘resize‘,
        recalc = function() 
          var clientWidth = docEl.clientWidth;
          var clientHeight = docEl.clientHeight;
          if (!clientWidth || !clientHeight) return;

          if (window.orientation === 90 || window.orientation === -90) 
             docEl.style.fontSize = 200 * (clientHeight / 750) + ‘px‘;
           else
             docEl.style.fontSize = 200 * (clientWidth / 750) + ‘px‘;
          
        ;
    if (!doc.addEventListener) 
        return;
    
    win.addEventListener(resizeEvt, recalc, false);
    doc.addEventListener(‘DOMContentLoaded‘, recalc, false);
)(document, window);

css使用:
未引入前

body 
    width: 750px;
    height: 640px;

引入后:除以100并将px换成rem

body 
    width: 7.5rem;
    height: 6.4rem;

换算的依据是

// 乘以100,px : rem = 100 : 1
var recalc = function() 
    var width = docEl.clientWidth;
    if (width / dpr > 750) 
        width = 750 * dpr;
    
    // 乘以100,px : rem = 100 : 1
    docEl.style.fontSize = 100 * (width / 750) + ‘px‘;
;

方法二 (推荐)

引入:页面开头处引入下面这段代码,用于动态计算font-size,或者单独放入一个文件,引入文件也可以

(function(win, lib) 
    var doc = win.document;
    var docEl = doc.documentElement;
    var metaEl = doc.querySelector(‘meta[name="viewport"]‘);
    var flexibleEl = doc.querySelector(‘meta[name="flexible"]‘);
    var dpr = 0;
    var scale = 0;
    var tid;
    var flexible = lib.flexible || (lib.flexible = );

    if (metaEl) 
        var match = metaEl.getAttribute(‘content‘).match(/initial-scale=([d.]+)/);
        if (match) 
            scale = parseFloat(match[1]);
            dpr = parseInt(1 / scale);
        
     else if (flexibleEl) 
        var content = flexibleEl.getAttribute(‘content‘);
        if (content) 
            var initialDpr = content.match(/initial-dpr=([d.]+)/);
            var maximumDpr = content.match(/maximum-dpr=([d.]+)/);
            if (initialDpr) 
                dpr = parseFloat(initialDpr[1]);
                scale = parseFloat((1 / dpr).toFixed(2));
            
            if (maximumDpr) 
                dpr = parseFloat(maximumDpr[1]);
                scale = parseFloat((1 / dpr).toFixed(2));
            
        
    

    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;
    

    docEl.setAttribute(‘data-dpr‘, dpr);
    if (!metaEl) 
        metaEl = doc.createElement(‘meta‘);
        metaEl.setAttribute(‘name‘, ‘viewport‘);
        metaEl.setAttribute(‘content‘, ‘initial-scale=‘ + scale + ‘, maximum-scale=‘ + scale + ‘, minimum-scale=‘ + scale + ‘, user-scalable=no‘);
        if (docEl.firstElementChild) 
            docEl.firstElementChild.appendChild(metaEl);
         else 
            var wrap = doc.createElement(‘div‘);
            wrap.appendChild(metaEl);
            doc.write(wrap.innerHTML);
        
    

    function refreshRem() 
        var width = docEl.getBoundingClientRect().width;
        // 适配平板
        if (width / dpr > 540) 
            width = 540 * dpr;
        
        var rem = width / 10;
        docEl.style.fontSize = rem + ‘px‘;
        flexible.rem = win.rem = rem;
    

    win.addEventListener(‘resize‘, function() 
        clearTimeout(tid);
        tid = setTimeout(refreshRem, 300);
    , false);
    win.addEventListener(‘pageshow‘, function(e) 
        if (e.persisted) 
            clearTimeout(tid);
            tid = setTimeout(refreshRem, 300);
        
    , false);

    if (doc.readyState === ‘complete‘) 
        doc.body.style.fontSize = 12 * dpr + ‘px‘;
     else 
        doc.addEventListener(‘DOMContentLoaded‘, function(e) 
            doc.body.style.fontSize = 12 * dpr + ‘px‘;
        , false);
    


    refreshRem();

    flexible.dpr = win.dpr = dpr;
    flexible.refreshRem = refreshRem;
    flexible.rem2px = function(d) 
        var val = parseFloat(d) * this.rem;
        if (typeof d === ‘string‘ && d.match(/rem$/)) 
            val += ‘px‘;
        
        return val;
    
    flexible.px2rem = function(d) 
        var val = parseFloat(d) / this.rem;
        if (typeof d === ‘string‘ && d.match(/px$/)) 
            val += ‘rem‘;
        
        return val;
    

)(window, window[‘lib‘] || (window[‘lib‘] = ));

css使用:
未引入前

body 
    width: 750px;
    height: 640px;

引入后

@font-size-base: 75;
body 
    width: 750rem/@font-size-base;
    height: 640rem/@font-size-base;

换算依据:

function refreshRem() 
    var width = docEl.getBoundingClientRect().width;
    // 适配平板
    if (width / dpr > 540) 
        width = 540 * dpr;
    
    var rem = width / 10;
    docEl.style.fontSize = rem + ‘px‘;
    flexible.rem = win.rem = rem;

这边是用的less,如果您没有用less,就需要手动计算,当然也可以转化为px : rem = 100 : 1。 如果想转化为px : rem = 100 : 1,可以修改上面的refreshRem函数:

function refreshRem() 
    var width = docEl.getBoundingClientRect().width
    // 适配平板
    if (width / dpr > 750) 
      width = 750 * dpr
    
    var rem = 100 * (width / 750)
    docEl.style.fontSize = rem + ‘px‘
    flexible.rem = win.rem = rem;

未引入前

body 
    width: 750px;
    height: 640px;

引入后:除以100并将px换成rem

body 
    width: 7.5rem;
    height: 6.4rem;

换算依据就是上面修改的代码:

function refreshRem() 
    var width = docEl.getBoundingClientRect().width
    // 适配平板
    if (width / dpr > 750) 
      width = 750 * dpr
    
    var rem = 100 * (width / 750)
    docEl.style.fontSize = rem + ‘px‘
    flexible.rem = win.rem = rem;

方法三

1rem等于html根元素设定的font-size的px值

const BASE_SIZE = 100 // 基准大小
const DEVICE_WIDTH = 750 // 设备宽度

// 设置 rem 函数
const setRem = () => 
  const scale = document.documentElement.clientWidth / DEVICE_WIDTH
  if (scale > 1) 
    // 最大尺寸
    document.documentElement.style.fontSize = BASE_SIZE + ‘px‘
   else 
    // 最小尺寸
    document.documentElement.style.fontSize = BASE_SIZE * scale + ‘px‘
  

// 初始化
setRem()
// 改变窗口大小时重新设置 rem
window.onresize = setRem

手机端页面自适应解决方案—rem布局

...始写移动端页面的同学都要面对页面自适应的问题,当然解决方案很多,比如:百分比布局,弹性布局flex(什么是flex),也都能获得不错的效果,这里主要介绍的是本人在实践中用的最顺手最简单的布局方案——rem(什... 查看详情

手机端页面自适应解决方案—rem布局(该方案目前已过时)

...始写移动端页面的同学都要面对页面自适应的问题,当然解决方案很多,比如:百分比布局,弹性布局flex(什么是flex),也都能获得不错的效果,这里主要介绍的是本人在实践中用的最顺手最简单的布局方案——rem(什么是rem... 查看详情

手机端页面自适应解决方案—rem布局(进阶版,附源码示例)

...190000007350680一年前笔者写了一篇 《手机端页面自适应解决方案—rem布局》,意外受到很多朋友的关注和喜欢。但随着时间的推移,该方案已然过时,故为大家介绍一个目前我极力推荐使用的,更加完美的方案——rem布局(进... 查看详情

移动端自适应布局方案尝试

原文地址:移动端自适应布局方案尝试问题刚开始接触移动端H5页面的时候最困扰的几个问题是:6或6p上明明是1px的边框怎么就成了2px或3px辣么粗!图片,div等如何等比自适应设计图后来慢慢知道了第一点是由于retina屏幕下设备... 查看详情

手机端页面自适应解决方案—rem布局

只需在页面引入这段原生js代码就可以了1234567891011121314151617(function(doc,win){       var docEl=doc.documentElement,           查看详情

html5移动端页面自适应布局详解(阿里rem布局)

在移动设备上进行网页的重构或开发,首先得搞明白的就是移动设备上的viewport,通读网上的各种对于viewport的解释之后大概viewport可以理解为三种1。layoutviewport ,也就是这个浏览器默认的viewport2。visualviewport  , 浏览... 查看详情

rem手机端页面自适应布局(待修正下一篇完美布局)

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"><script&g 查看详情

移动端自适应布局方案尝试

问题刚开始接触移动端H5页面的时候最困扰的几个问题是:6或6p上明明是1px的边框怎么就成了2px或3px辣么粗!图片,div等如何等比自适应设计图后来慢慢知道了第一点是由于retina屏幕下设备像素比的问题造成,第二点知道了单位r... 查看详情

70.js---利用原生js做手机端网页自适应解决方案rem布局(代码片段)

...bsp;     利用原生js做手机端网页自适应解决方案rem布局刚开始我用的是下面这段代码,然后js通过外部链接引入,最后每次用手机刷新网页的时候都会出现缩略图functiongetRem(pwidth,prem)varhtml=document.getElementsByTagName... 查看详情

移动端自适应处理页面布局

处理页面大概会有若干种方案:第一种就是使用bootstrap;自己使用自适应单位常用的rem,em,及别人封装好的插件flexble.js;在使用flexble.js;时发现两个问题,高度没有很好的展现,有时会比设计稿低,会造成页面扁平不好看,第二种就... 查看详情

移动端网页rem自适应布局

(function(doc,win){varDocElement=doc.documentElement;varRsizeEvent=‘orientationchange‘inwindow?‘orientationchange‘:‘resize‘;functionResetSize(){vardeviceWidth=DocElement.clientWidth;if(!deviceWidth){r 查看详情

calc计算,移动端布局(代码片段)

在做移动端页面布局的时候,需要做到响应式,也就是文字会随着页面的大小改变以后文字的大小和div的宽高等比例跟着改变。rem单位是相对于html的font-size的来的,所以用rem单位就可以实现。我们只要把HTML的font-size设置自适应... 查看详情

vue判断电脑还是手机设备pc端自适应移动端rem布局

参考技术Apc端所有的页面和移动端都写在一个项目里这时候就需要我在登录的时候判断是什么设备然后跳到相应的页面采用不同的样式可以写在一个js文件里,然后在main.js里统一引入如果是手机端的话我要采用rem布局设计稿是640... 查看详情

移动端适配方案-rem(基础篇)

    常见移动web适配方案一般有3种方法,如下图:      ①:定高,宽度百分比(百分比适配简单,一般用来做一些适配性不高的页面,比如只有一些文字和图片等简单的屏幕适配)    ②:flex(更多的用于复... 查看详情

移动端页面适配问题

移动端页面满屏自适应方案(采用rem作为单位,设计稿为750*1334)修改自阿里的lib-flexible,与lib-flexible相比,删除了dpr,保留rem满屏自适应,要求设计稿为750*1334单位换算为1rem=50px        代码引入:&l... 查看详情

rem-移动前端自适应适配布局解决方案和比较(转载)

...度,使用一个模式,加上少许的媒体查询方案使用flexbox解决方案使用百分比加媒体查询使用rem淘宝最近开源的一个框架和网易的框架有同工之异。都是采用rem实现一稿解决所有设置自适应。在没出来这种方案之 查看详情

自适应

 在最近的移动端布局当中,最炙手可热的方式便是使用rem进行元素的布局。以下便是从最近的文章中所总结出来的一点东西。首先,我们必须有以下的疑问:rem的本质是什么?rem如何实现自适应布局?如何根据设计稿来调整... 查看详情

rem自适应

...多底层的内容都需要自己去解决,幸好的是这次只是关于移动端的内容,还不至于去向着jquery的方向码代码。言归正传,前几天在处理底色切换的时候,由于需要做到自适应即盒子的高度随着盒子的宽度变化,各种找资料发现了... 查看详情