Watch Star

Janking / Infinite-f2e-clubJavaScriptMIT

(续)adaptive解读及应用 #IC1C9

待办的
chess_cai 成员  创建于

adaptive解读及应用

本文是上一篇《flexible解读及应用》 的续文,请结合看。 adaptive是基于flexible的h5翻屏适配解决方案,是对flexible的dpr和fontSize的计算结果,进一步精准计算并动态改写。简言之:flexible适配设备宽度,adaptive适配设备高度。

giuhub:https://github.com/chesscai/flexible-adaptive/

怎么样算适配好

一个场景:一副满屏的背景图片,怎么样才是适配到各个设备?长宽比不同的设备,总要有所取舍,你想 background-size: 100% | contain | cover; 100%会拉伸,contain会留白,cover会裁切。这时候傻逼运营来了:这页面有bug,图片显示不全balabala。我就问你what are you fucking doing? 回到正题,估计做翻屏遇到最多的问题就是页面元素显示不全了吧,因为往往浏览器五花八门的标题栏和功能区会占据可视区域。 以本工厂单屏设计稿为例: 640 * 1136(i5,ISUX给的宽高比则比较合理:320 * 504,减去了标题栏高度), 另一个极端机子MX4 可视区是384 * 518,问你死了没 极端 那么这种情况下,这样显示比较合理?显然,信息肯定要显示全,排版不能乱。要满足此需求,估计只有缩小元素了吧,如果有更好的点子还望不吝赐教。 排版

如何用高度计算fontSize

使用rem的好处就是只需关心根元素fontSize,flexible已经计算好宽度的fontSize了,以下计算校准值:

	var autoScale = function(){
	    var designW = 640,                               //设计稿宽
	        designH = 1136,                              //设计稿高
	        winW = docEl.clientWidth,                    //实际可视区宽
	        winH = docEl.clientHeight,                   //实际可视区高
	        idealFs = parseFloat(docEl.style.fontSize),  //理想基准字号(既flexible计算字号)
	        idealH = winW * designH / designW,           //理想可视区高(根据设计稿等比缩放计算高度)
	        exactFs = winH * idealFs / idealH,           //准确基准字号(最终结果)
	        
	    docEl.style.fontSize = exactFs + 'px';
	};

上码定义了设计稿宽高,实际可视区宽高,理想情况下:这两组数据的比值相等,那么也就没这里什么事了。然鹅这是不可能滴,实际上,iphone5 640 * 1136 的宽高比是比较极端的了,相比绝大部分机子是比较“高”的,所以计算出最终fs结果是变小的。 分析一下以上函数:

1.根据设计稿宽高(已知)和实际可视宽度计算出理想可视区高idealH,所谓理想,既是上文提到的理想宽高比值与设计稿的相等 2.根据理想可视区高idealH计算出准确基准字号exactFs 3.把exactFs赋值给根元素就可以了

以下为UC的测试数据,可视宽度(window.innerWidth)可视高度(window.innerHeight)

可视宽度 可视高度(含导航栏) 可视高度(不含导航栏) dpr
iphone6 375 559 628 2
Snote4 360 519 567 4
MI4 360 514 564 4
P8 360 470 519 2
Honor3C 350 518 567 2
Mnote2 360 519 567 3
MX4 384 518 567 3

生产中遇到的坑

坑1:安卓机获取可视区高前后不一致

测试中发现,“前后”具体体现在滚动过页面,首次加载的高度比滚动后二次加载的高度小,得益于之前调研上表时做了大量测试,原因是滚动后浏览器会收起标题栏释放了占有的高度,这就导致了页面元素太大而溢出可视区,不信?试试。那么既然问题出在滚动上,以其人之道还治其人之身:

	//以i6 uc为例
	alert(docEl.clientHeight);//559
	win.scrollTo(0,0);
	alert(docEl.clientHeight);//585,不错,是我要的结果

在autoScale函数前加入 win.scrollTo(0,0); 哼哼,这把该可以了吧

	var autoScale = function(){
		win.scrollTo(0,0);
		...
	}

什么!还是不行?bq。。。 long long after 我又回头看了flexible的源码,才发现

	win.addEventListener('resize', function() {
       clearTimeout(tid);
       tid = setTimeout(refreshRem, 300);
    }, false);

天了噜,win.scrollTo(0,0); 解决的问题,resize又让他一夜回到解放前。考虑到手机端resize的情况很少见,不像pc可以拖拽,于是为了配合adaptive,我把resize监听注释了。问题解决!

坑2:浏览器回退

之前没考虑到浏览器回退的情况,展哥提供的bug,发现会有放大情况。曾老师提供思路,于是问题很快解决。浏览器回退不会触发onload但会触发pageshow,之前adaptive没有监听pageshow,而flexible有,于是。。。 加了监听事件,大功告成。

优化

0.1.2版本加入了横竖屏判断和提示,横屏会添加遮罩,提示“请使用竖屏浏览”。

使用

example:http://70.vrm.cn/8

在head引入flexible.js,adaptive.js,有前后依赖关系

	<script src="/local-assets/js/flexible/flexible-0.3.2.js"></script>
	<script src="/local-assets/js/flexible/adaptive-0.1.2.js"></script>

在flexible基础上无痛修改,其他该怎么写怎么写,请参照前文。 另外:如有设计稿尺寸不一致,只需修改 designW,designH的值即可。

等等,wap页面还要兼容pc? 好吧,pc怎么排版合适?想了想:高度满屏,宽度自适应可以不 pc,wap代码分管的,直接在pc以上js文件后插入;如果用一份代码,判断ua去吧~

	<script>
        (function(win,doc){
            var wh = win.innerHeight;
            var dh = 1136;
            var dw = 640;
            var h = wh;
            var w = dw * wh / dh;
            var docEl = doc.documentElement;
            setTimeout(function(){
                docEl.style.cssText = 'width:'+ w +'px;height:'+ h +'px;margin:0 auto;font-size:'+ w/10 + 'px';},300);
        })(window,document);
    </script>

结语

本文到此结束,开发中遇到的问题均已修复,如发现任何bug或可优化的地方欢迎随时回复交流

104617_janking 共2人参与

评论 (5)

104617_janking
Janking 2017-02-12 12:49 拥有者

我就喜欢看这种文章!

加鸡腿!

104617_janking
Janking 2017-02-12 12:54 拥有者
chess_cai 2017-02-12 14:02 成员

@Janking 考虑到烟花的出镜率太低了 不值得写

104617_janking
Janking 2017-02-12 14:04 拥有者

@chess_cai :joy: 中国放烟花除了过年还是有很多其他场景的。

chess_cai 2017-02-12 14:35 成员

@Janking 不是 是在页面中就出现那几秒

登录 后才可以发表评论

负责人
标签
移动端适配
工作心得
里程碑
关联分支
开始时间
未设置
结束时间
未设置
置顶选项
优先级

搜索帮助