由于业务需要,领导要求我做一个适配大部分手机屏幕分辨率的网页版项目出来。我在html端的开发参与较少,因此这个项目是边学边做的。首先去了解过Bootstrap,这是一个很强大的前端开发框架,还提供了响应式布局和流式布局等方案来解决多端适配,我们的业务要求不同分辨率下排版不乱、图片等比例拉伸,使用响应式布局来说成本太高,而流式布局又不符合要求,经过四处寻找、学习,最后决定使用rem来实现。
rem是相对于根元素<html>,会根据font-size改变大小,这样就意味着,我们只需要在根元素确定一个px字号,则可以来算出元素的宽高。网上关于ram的介绍挺多,但是大部分只是单纯的转载粘贴复制,直接按照他们转载的来操作根本达不到屏幕适配的效果,我会在笔记里特别标注出他们遗漏掉的地方。
大多数浏览器的默认字号是16px,因此1rem=16px,但是这样不方便我们px和rem的换算,假设1rem=10px,那么100px=10rem,25px=0.25rem。这样就好换算很多,于是就有了以下样式作为基准样式:
html
{
font-size: 62.5%; /* 10 ÷ 16 × 100% = 62.5% */
}
但是由于chrome在字体小于12px时都当12px处理,我们可以将html字体大小设置为625%,即1rem=100px。
然后将设计师提供的设计图的宽度确定为基准宽度,html字体大小适配为:浏览器的宽度/基准宽度*625% 。
这是rem适配的关键,然而大部分文章都漏掉了,感谢这篇博客:前端页面适配的rem换算
rem适配的代码如下:
/*当前设备屏幕宽度*/
var mWidth = document.documentElement.clientWidth;
/*假设设计图的宽度是720px*/
var fontSize = mWidth / 720 * 625;
var obj = document.getElementsByTagName('html')[0];
obj.style.fontSize = fontSize + "%";
如果还需要考虑屏幕旋转等分辨率实时改变的情况,可以把适配的代码放在window.onresize里:
window.onresize = function () {
var mWidth = document.documentElement.clientWidth;
var fontSize = mWidth / 720 * 625;
var obj = document.getElementsByTagName('html')[0];
obj.style.fontSize = fontSize + "%";
}
接下来按照设计图完成页面,单位使用rem就行。
在末尾记录一些处理该项目时遇到的小坑:
1.rem和bootstrapt等框架搭配使用的时候偶尔会被框架的样式覆盖,通常这些样式是px单位的。
解决方式:手动修改。
2.IOS端<button>(暂时只发现了该元素)渲染方式与其他内核内核浏览器不一样,实际宽度略小于CSS中设置的宽度从而导致展现效果的差异。
解决方式:手动微调宽度。
3.IOS端document.onclick事件无法触发,IOS端像<div>这样本身无法点击的标签无法触发onclick事件。
解决方式:首先绑定onclick更换为一个需要监听点击事件区域的父标签,可以为<div>等无法点击的标签,然后给该标签添加CSS样式:cursor:pointer;
4.IOS端onclick事件中通过document.activeElement获得点击的元素会拿到<body>标签而不是点击的元素,这是因为页面加载时document.activeElement为null,加载完成后则指向了<body>,为了在onclick事件中拿到正确的元素,需要先给元素设置焦点,再调用activeElement。
解决方式:
document.getElementById(id).onclick = function (e) {
e.target.focus();
var obj = document.activeElement;
}
5.iframe自适应高度:
解决方式:
window.onresize = function () {
var ifm = document.getElementById("myIframe");
ifm.height = (ifm.Document ? ifm.Document.body.scrollHeight : ifm.contentDocument.body.offsetHeight);