移动端适配js
第一种、参考网易的 (我现在用这个多)
https://www.cnblogs.com/well-nice/p/5509589.html
1 var deviceWidth = document.documentElement.clientWidth; 2 if(deviceWidth > 750) {
deviceWidth = 750;
}
3 document.documentElement.style.fontSize = deviceWidth / 7.5 + 'px';
备注:body要加个样式:width:7.5rem
这是针对设计图为750的,如果是640,就/640
(1)先拿设计稿竖着的横向分辨率除以100得到body元素的宽度:
1 如果设计稿基于iphone6,横向分辨率为750,body的width为750 / 100 = 7.5rem 2 如果设计稿基于iphone4/5,横向分辨率为640,body的width为640 / 100 = 6.4rem
- (2)布局时,设计图标注的尺寸除以100得到css中的尺寸,比如下图:
- 播放器高度为210px,写样式的时候css应该这么写:height: 2.1rem。之所以取一个100作为参照,就是为了这里计算rem的方便!
- (3)在dom ready以后,通过以下代码设置html的font-size:
-
1 document.documentElement.style.fontSize = document.documentElement.clientWidth / 6.4 + 'px';
- 6.4只是举个例子,如果是750的设计稿,应该除以7.5。
- (4)font-size可能需要额外的媒介查询,并且font-size不能使用rem,如网易的设置:
-
1 @media screen and (max-width:321px){ 2 .m-navlist{font-size:15px} 3 } 4 5 @media screen and (min-width:321px) and (max-width:400px){ 6 .m-navlist{font-size:16px} 7 } 8 9 @media screen and (min-width:400px){ 10 .m-navlist{font-size:18px} 11 }
最后还有2个情况要说明:
第一,如果采用网易这种做法,视口要如下设置:
-
1 <meta name="viewport" content="initial-scale=1,maximum-scale=1, minimum-scale=1">
第二,当deviceWidth大于设计稿的横向分辨率时,html的font-size始终等于横向分辨率/body元素宽:
- 第二,当deviceWidth大于设计稿的横向分辨率时,html的font-size始终等于横向分辨率/body元素宽:
-
之所以这么干,是因为当deviceWidth大于640时,则物理分辨率大于1280(这就看设备的devicePixelRatio这个值了),应该去访问pc网站了。事实就是这样,你从手机访问网易,看到的是触屏版的页面,如果从pad访问,看到的就是电脑版的页面。如果你也想这么干,只要把总结中第三步的代码稍微改一下就行了:
-
//得到手机屏幕的宽度
1 var deviceWidth = document.documentElement.clientWidth || document.body.clientWidth;
2 if(deviceWidth > 640) deviceWidth = 640;
3 document.documentElement.style.fontSize = deviceWidth / 6.4 + 'px';备注:body要加个样式:width:7.5rem
第三种 、参考淘宝的
https://www.cnblogs.com/well-nice/p/5509589.html
看看淘宝在不同分辨率下,呈现的效果:
淘宝的效果跟网易的效果其实是类似的,随着分辨率的变化,页面元素的尺寸和间距都相应变化,这是因为淘宝的尺寸也是使用了rem的原因。在介绍它的做法之前,先来了解一点关于viewport的知识,通常我们采用如下代码设置viewport:
1 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
这样整个网页在设备内显示时的页面宽度就会等于设备逻辑像素大小,也就是device-width。这个device-width的计算公式为:
设备的物理分辨率/(devicePixelRatio * scale),在scale为1的情况下,device-width = 设备的物理分辨率/devicePixelRatio 。
devicePixelRatio称为设备像素比,每款设备的devicePixelRatio都是已知,并且不变的,目前高清屏,普遍都是2,不过还有更高的,比如2.5, 3 等,我魅族note的手机的devicePixelRatio就是3。淘宝触屏版布局的前提就是viewport的scale根据devicePixelRatio动态设置:
在devicePixelRatio为2的时候,scale为0.5
在devicePixelRatio为3的时候,scale为0.3333
这么做目的当然是为了保证页面的大小与设计稿保持一致了,比如设计稿如果是750的横向分辨率,那么实际页面的device-width,以iphone6来说,也等于750,这样的话设计稿上标注的尺寸只要除以某一个值就能够转换为rem了。通过js设置viewport的方法如下:
1 var scale = 1 / devicePixelRatio; 2 document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
淘宝布局的第二个要点,就是html元素的font-size的计算公式,font-size = deviceWidth / 10:
接下来要解决的问题是,元素的尺寸该如何计算,比如说设计稿上某一个元素的宽为150px,换算成rem应该怎么算呢?这个值等于设计稿标注尺寸/该设计稿对应的html的font-size。拿淘宝来说的,他们用的设计稿是750的,所以html的font-size就是75,如果某个元素时150px的宽,换算成rem就是150 / 75 = 2rem。总结下淘宝的这些做法:
- (1)动态设置viewport的scale
-
1 var scale = 1 / devicePixelRatio; 2 document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
(2)动态计算html的font-size
-
1 document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px';
- (3)布局的时候,各元素的css尺寸=设计稿标注尺寸/设计稿横向分辨率/10
- (4)font-size可能需要额外的媒介查询,并且font-size不使用rem,这一点跟网易是一样的。
- 最后还有一个情况要说明,跟网易一样,淘宝也设置了一个临界点,当设备竖着时横向物理分辨率大于1080时,html的font-size就不会变化了,原因也是一样的,分辨率已经可以去访问电脑版页面了。
-
关于这种做法的具体实现,淘宝已经给我们提供了一个开源的解决方案,具体请查看:
5. 比较网易与淘宝的做法
共同点:
- 都能适配所有的手机设备,对于pad,网易与淘宝都会跳转到pc页面,不再使用触屏版的页面
- 都需要动态设置html的font-size
- 布局时各元素的尺寸值都是根据设计稿标注的尺寸计算出来,由于html的font-size是动态调整的,所以能够做到不同分辨率下页面布局呈现等比变化
- 容器元素的font-size都不用rem,需要额外地对font-size做媒介查询
- 都能应用于尺寸不同的设计稿,只要按以上总结的方法去用就可以了
不同点
- 淘宝的设计稿是基于750的横向分辨率,网易的设计稿是基于640的横向分辨率,还要强调的是,虽然设计稿不同,但是最终的结果是一致的,设计稿的尺寸一个公司设计人员的工作标准,每个公司不一样而已
- 淘宝还需要动态设置viewport的scale,网易不用
- 最重要的区别就是:网易的做法,rem值很好计算,淘宝的做法肯定得用计算器才能用好了 。不过要是你使用了less和sass这样的css处理器,就好办多了,以淘宝跟less举例,我们可以这样编写less:
1 //定义一个变量和一个mixin 2 @baseFontSize: 75;//基于视觉稿横屏尺寸/100得出的基准font-size 3 .px2rem(@name, @px){ 4 @{name}: @px / @baseFontSize * 1rem; 5 } 6 7 //使用示例: 8 .container { 9 .px2rem(height, 240); 10 } 11 12 //less翻译结果: 13 .container { 14 height: 3.2rem; 15 }