一 媒体查询

  1. 通过媒体查询
    • 媒体查询的方式是李南江老师早期采用的布局方式
    • 它主要是通过查询设备的宽度来执行不同的 css 代码,最终达到界面的配置
  2. 媒体查询优势
    • 简单, 哪里不对改哪里
    • 调整屏幕宽度的时候不用刷新页面即可响应式展示
    • 特别适合对移动端和 PC 维护同一套代码的时候
  3. 媒体查询劣势
    • 由于移动端和PC端维护同一套代码, 所以代码量比较大, 维护不方便
    • 为了兼顾大屏幕或高清设备,会造成其他设备资源浪费,特别是加载图片资源
    • 为了兼顾移动端和PC端各自响应式的展示效果,难免会损失各自特有的交互方式
  4. 应用场景
    • 对于比较简单(界面不复杂)的网页, 诸如: 企业官网、宣传单页等
    • 我们可以通过媒体查询、伸缩布局、Bootstrap 来实现响应式站点
  • 对于比较复杂(界面复杂)的网页, 诸如: 电商、团购等 更多的则是还是 PC 端一套代码, 移动端一套代码

二 页面自动跳转 + 媒体查询

  • 在PC端打开自动打开PC端界面
  • 在移动端打开自动打开移动端界面

自动跳转实现步骤

  1. 默认打开 PC 端界面
  2. 在PC端界面中通过 BOM 拿到当前浏览器信息
  3. 通过正则判断当前浏览器是否是移动端浏览器
  4. 通过 BOM 的 location 对象实现跳转到移动端界面
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<title>移动端常用适配方案-界面自动跳转</title>
	</head>
	<body>
		<script>
			/*
                PC:     Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
                移动端: Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1
                移动端: Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Mobile Safari/537.36
    		*/
			// let userAgentInfo = navigator.userAgent;
			// console.log(userAgentInfo);
			function isPc() {
			    let userAgentInfo = navigator.userAgent;
			    if(/iphone/i.test(userAgentInfo)){
			        return false;
			    }else if(/android/i.test(userAgentInfo)){
			        return false;
			    }
			    return true;
			}
			if(!isPc()){
			    location.href = "http://m.jd.com";
			}
		</script>
	</body>
</html>

复制代码

跳转到移动端结合媒体查询

  1. 通过媒体查询 + rem
    • 虽然我们将移动端独立到一套代码中了, 但是由于==移动端也有很多的屏幕尺寸==, 所以也需要进行适配
    • 例如
      • iPhone3/4/5: 320px
      • iPhone6/7/8: 375px
      • iPhoneX/plus: 414px
    • 当下在企业开发中设计师提供给我们的移动端设计图片是 ==750*xxx== 的或者 1125*xxx 的
    • 所以我们需要对设计师提供的图片进行等比缩放, 这样才能 1:1 还原设计图片
  2. 如何等比缩放? (下面的操作使得等比缩放易于操作)
    1. 将设计图片等分为指定份数,求出每一份的大小 例如: 750 设计图片分为 7.5 份(仅是为了每份是 100px 好算), 那么每一份的大小就是100px
    2. 将目标屏幕也等分为指定份数,求出每一份的大小 例如: 375 屏幕====分为 7.5 份, 那么每一份的大小就是 50px (这不是巧了吗这不是)
    3. 按设计图等比缩放,于是有 原始元素尺寸 / 原始图片每一份大小 = 等比缩放后的尺寸 / 目标屏幕每一份大小 => 原始元素尺寸 / 原始图片每一份大小 * 目标屏幕每一份大小(不一定是 px 呀) = 等比缩放后的尺寸 (这里其实也有计算, 原屏幕分 7.5, 目标屏幕也分 7.5, 比例上没变, 数学牛逼了) 例如: 设计图片上有一个 150*150 的图片, 我想等比缩放显示到 375 屏幕上 那么: 150 / 100 * 50 = 1.5*50 = 75px
  3. 如何在前端开发中应用这个计算公式? (用 rem 而不是 px 来算的话)
    1. 以 2.3 的代码为例, 我们设根元素字号为 50px (html 的 font-size: 50px) (==也就是目标屏幕一份的像素值==)则有图片 375 屏幕上为 1.5rem
    2. 使用时只需要用 “(原始元素尺寸 / 原始图片每一份大小)rem” 即可
      • 150 / 100 = 1.5rem
      • 1rem = 50px, 1.5rem === 1.5*50 = 75px
  4. 大公司应用实例
    1. 网易新闻
      • 750/100=7.5
      • 375/7.5=50;
      • 320/7.5=42.7;
    2. 苏宁易购
      • 750/50=15
      • 375/15=25
      • 320/15=21.33

以上可以看出: 结合 rem, 我们只需根据不同设备更改 html 的 font-size 值即可

三 页面自动跳转 + JS 计算 (好)

在方案二的基础上, 将媒体查询改为==用 JS 计算每种设备的根字号大小== (7.5 是份数)

document.documentElement.style.fontSize = window.innerWidth / 7.5 + "px";

// 注意注意注意: 这里 innerWidth 数值上是移动设备的 CSS 像素!!!
复制代码

JS 计算 vs 媒体查询

  • 通过 JS 动态计算根字号
    • 好处: 不用写很多的媒体查询
    • 坏处: 切换了屏幕尺寸之后需要刷新界面才有效
  • 通过媒体查询设置根字号
    • 好处: 如果切换了屏幕的尺寸不需要重新刷新界面
    • 坏处: 有多少种尺寸, 就要写多少个 @media screen and (min-width: 几几px)

四 视口缩放 (==完美==)

==注意注意注意:== ==这里 innerWidth 数值上是移动设备的 CSS 像素!!! 针对的是 css 像素和物理像素并非一比一的问题== ==通过缩放我们操作的 px 值仍然是物理像素, 于是原来用 rem 来达成线性映射的目的就仍能达成==

  1. 如何解决设备像素和 CSS 像素不一样的问题?
    • 如果设备像素和 CSS 像素一样, 那么无需处理不会带来任何负面影响
    • 如果设备像素是 CSS 像素的 2 倍, 那么我们只需将 CSS 像素缩小一半即可 (==所以这里我们是希望写的像素值是直接给到物理像素的==, 缩小后 1px 对在了一物理像素上)
    • 但是有时候设备像素可能是 CSS 像素的 3倍/4倍…
  2. 获取设备像素比 DPR(Device Pixel Ratio)
    • DPR = 设备像素 / CSS像素
    • iPhone3GS : 320 / 320 = 1
    • iPhone4S: 640 / 320 = 2
    • iPhone678: 750 / 375 = 2
    • iPhoneX: 1125 / 375 = 3 在 JS 中我们可以通过 window.devicePixelRatio 获取当前的设备像素
      console.log(window.devicePixelRatio);
      复制代码
  3. 如何缩小? 通过 <meta name="viewport"> 的initial-scale属性来缩小 注意点: 缩放视口后视口大小会发生变化
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>移动端常用适配方案四</title>
        <script>
            let scale = 1.0 / window.devicePixelRatio; // 算出希望视口缩小的倍数, 缩小后 1px  对在了一物理像素上
            let text = `<meta name="viewport" content="width=device-width, initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale}, user-scalable=no">`;
            document.write(text);
       
            document.documentElement.style.fontSize = window.innerWidth / 7.5 + "px";
        </script>
    </head>
    <body>
    </body>
    </html>
       
    <!--
    这样操作后, 缩小后 1px 对在了一物理像素上, 
    结合 rem 是相对于根元素的字号,
    而字号设置是按份数来线性映射的,
    于是这样是按屏幕比例(份数)设置
    也就能起到预期的效果
    -->
    复制代码

    重要的理解 (加个特殊颜色, 这个真的通透了)

    这样缩放后, 缩小后 CSS 里写的 1px 对在了一物理像素上, 结合 rem 是相对于根元素的字号, 而字号设置是根据物理像素按份数来线性映射的, 于是这样是按屏幕比例(份数)设置也就能起到预期的效果

    <!DOCTYPE html>
    <html lang="en">
       <head>
       	<meta charset="UTF-8" />
       	<title>视口缩放的本质是使 innerWidth 值变成物理像素值, 使原来的线性映射逻辑成立</title>
       	<script>
               // 算出希望视口缩小的倍数, 缩小后 1px 对在了一物理像素上
       		let scale = 1.0 / window.devicePixelRatio;
       		let text = `<meta name="viewport" content="width=device-width, initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale}, user-scalable=no">`;
       		document.write(text);
    
       		document.documentElement.style.fontSize =
       			window.innerWidth / 7.5 + "px";
       		console.log(window.innerWidth);
       	</script>
       </head>
       <body></body>
    </html>

 

[声明]本站素材来自用户分享,仅限学习交流请勿用于商业用途,如损害你的权益请联系客服QQ:1098510317给予处理。
站库云-前端开发学习平台 » 移动端适配方案

发表评论

提供优质的资源,供前端开发者们学习

网站案例 优化案例