前言
最近在开发公司官网的时候由于业务方、产品都没有明确开发响应式网站,就按以前旧官网1920px的桌面端以及750px的移动端开发两套适配解决方案,在领导们开会时投屏电视以及苹果电脑都出现了两边留白,因为之前在网上找了一套css属性zoom的算法是根据设备的像素比window.devicePixelRatio来进行倍数缩放,也因为设计稿是1920px但显示的设备分辨率都在2056px导致铺不满设备,又不能推翻重新开发响应式网站,在原基础上用技术手段去实现。
解决方案:
之前一直被网上的解决方案带偏,经过仔细的思考后决定还是不能使用像素比来处理缩放这样会存在偏差,其实解决很简单你只要拿到body的真是宽度就行然后除以设计稿的宽度就是你的缩放比,你也可以根据window.screen.width * window.devicePixelRatio拿到物理设备分辨率,window.innerWidth获取的真实视窗宽度 除以设计稿1920就是zoom的缩放比,不废话上代码。
第一步:
let viewportWidth = window.innerWidth || document.documentElement.clientWidth;
document.body.style.zoom = (viewportWidth / 1920 * 100000) / 100000;
window.addEventListener('resize', function() {
let viewportWidth = window.innerWidth || document.documentElement.clientWidth;
document.body.style.zoom = (viewportWidth / 1920 * 100000) / 100000;
});
在经过上十款平板测试发现要调整meta的viewport的默认缩放比,包含横屏以及竖屏状态,如果调整默认缩放initial-scale = 1会导致布局文字错乱。
第二步:
function isOrientationLandscape() {
return window.matchMedia("(orientation: landscape)").matches;
}
function isOrientationPortrait() {
return window.matchMedia("(orientation: portrait)").matches;
}
let viewport = document.querySelector("meta[name=viewport]");
// 使用示例
if (isOrientationLandscape()) {
console.log("设备处于横屏模式");
viewport.setAttribute('content', 'width=device-width,initial-scale = 0.74,maximum-scale=1.0, minimum-scale=0.74, user-scalable=no');
} else if (isOrientationPortrait()) {
viewport.setAttribute('content', 'width=device-width,initial-scale = 0.55,maximum-scale=1.0, minimum-scale=0.55, user-scalable=no');
console.log("设备处于竖屏模式");
}
// 发生旋转屏幕要刷新页面重新适配
function handleOrientationChange() {
window.location.reload()
}
// 监听方向变化事件
window.addEventListener('orientationchange', handleOrientationChange);
衍生的副作用:
① 在平板桌面模式下会导致导航的hover事件出现问题,可以用js来判断是不是触摸屏设备结合Class来处理
//判断桌面移动端;默认在body加上Class no-touch
if(navigator.maxTouchPoints > 0) {
$('body').removeClass('no-touch');
}
css调整下拉框的展示
② 如果页面涉及到获取滚动条距离 元素距离的要用缩放比反推缩放后的尺寸
//元素顶部距离乘以缩放比换算出真实缩放后的距离
$("div")[0].offsetTop * parseFloat(document.body.style.zoom)
③ 如果平板竖屏会出现底部留白, 如果要保证底部页脚铺满在屏幕下面可以在html标签设置 css
html { min-height:100vh;position: relative; }
footer 设置
footer { position: absolute;bottom: 0;left: 0;right: 0; }
这样底部页脚脱离文档流相对html定在底部。 然后默认在缩放的body设置包裹的div的padding-bottom 等于footer的高度,
调整前:
调整后:
ps:① 注意不要使用jquery 的 offset().top 来获取元素顶部距离,会实时变化数据,
② 您可以设置一个 CSS 属性来禁用这种反缩放效果,-webkit-text-size-adjust: none Chrome/Edge 浏览器支持无前缀的 text-size-adjust
,但 Safari 支持带有 -webkit
前缀的它。
③ 然后需要注意的一点就是页面在高清分辨率上字体不要设置自适应字体。