前言
叮咚~,测试小姐姐发消息说她的 windows 电脑上系统样式显示鬼畜了,于是我过去一看究竟,果然。。。,为了缓解尴尬,我还是淡定的安慰她,别慌别慌,小问题,于是赶紧回到座位研究解决办法。
由于前端在开发时使用的都是标准 ui 设计图,基本都是按照所以 1920*1080, 而小屏幕笔记本由于分辨率高,所以导致的显示元素变小,因此很多笔记本的默认显示都是放大 125%或者 150%。
如果页面比较简单就让多余的空白单边扩展,这样可以不受影响,但是如果页面遍布了引入的其他组件,就不好控制位置和大小了。
我查了一下,基本都是根据 window.screen.availHeight
来获取屏幕缩放比例,window.screen.availHeight > 1000
说明缩放选择的是 100%,否则是 125%、150%, 还有使用媒体查询的,直接拷贝过去试了一下一点用没有,但是我说明一下,这个肯定是一种解决方式,只是我仔细去研究,其他的同理,用了一下没有效果,想着显示设备应该都有 devicePixelRatio 这个属性把,于是打印了一下还真有,就去搜了相关,直接获取devicePixelRatio
,因为屏幕是可以缩放的,所以直接1/devicePixelRatio
就可以解决屏幕任意缩放了而现实内容固定了,如下:
我用的是 vue,所以我把它加在了 app.vue 下的:
export default { name: 'App', created () { const devicePixelRatio = window.devicePixelRatio // 获取下载的缩放 125% -> 1.25 150% -> 1.5 if (devicePixelRatio !== 1) { // 老 ie 可以提示 if (!! window.ActiveXObject || 'ActiveXObject' in window) { alert('balabala,去用 chrome 吧') } else { const c = document.querySelector('body') c.style.zoom = 1 / devicePixelRatio// 修改页面的缩放比例 } } } }
这里是屏幕任意缩放,不能是浏览器任意缩放,浏览器缩放会导致所有内容同时变大或变小,但是浏览器和屏幕是可以互相中和的,举个例子,笔记本屏幕方法 150%,那么浏览器一定是缩放 2/3 时可以显示原始的页面,因为他们共同影响页面元素的。
高级一点,在 src/utils 文件夹下新建 devicePixelRatio.js 文件:
class DevicePixelRatio { constructor() { //this.flag = false; } //获取系统类型 _getSystem() { let flag = false; var agent = navigator.userAgent.toLowerCase(); //现只针对 windows 处理,其它系统暂无该情况,如有,继续在此添加 if (agent.indexOf("windows") >= 0) { return true; } } //监听方法兼容写法 _addHandler(element, type, handler) { if (element.addEventListener) { element.addEventListener(type, handler, false); } else if (element.attachEvent) { element.attachEvent("on" + type, handler); } else { element["on" + type] = handler; } } //校正浏览器缩放比例 _correct() { let t = this; //页面 devicePixelRatio(设备像素比例)变化后,计算页面 body 标签 zoom 修改其大小,来抵消 devicePixelRatio 带来的变化。 document.getElementsByTagName('body')[0].style.zoom = 1 / window.devicePixelRatio; } //监听页面缩放 _watch() { let t = this; t._addHandler(window, 'resize', function() { //注意这个方法是解决全局有两个 window.resize //重新校正 t._correct() }) } //初始化页面比例 init() { let t = this; if (t._getSystem()) { //判断设备,目前只在 windows 系统下校正浏览器缩放比例 //初始化页面校正浏览器缩放比例 t._correct(); //开启监听页面缩放 t._watch(); } } } export default DevicePixelRatio;
然后,在 app.vue 中引入文件并使用:
import DevicePixelRatio from './utils/devicePixelRatio'; export default { name: "App", created() { new DevicePixelRatio().init(); } };
还有小伙伴说了,可以使用 rem 单位,将 px 转为 rem,可行。但是,我们项目所有单位都是 px, 全部转为 rem 工程量巨大…弃了(笑哭)。不过,别灰心,有现成的轮子,大家可以看看 px2rem 插件。
说到这儿,又有小伙伴问了,如何实现浏览器随意缩放,而页面内容自动适应屏幕大小呢?
话不多说,上代码:
export default { name: 'App', created () { this.$nextTick(() => { this.resizeFun() window.addEventListener('resize', this.resizeFun) }) }, methods: { resizeFun () { const devicePixelRatio = window.devicePixelRatio // 获取下载的缩放 125% -> 1.25 150% -> 1.5 if (devicePixelRatio !== 1) { // 如果在笔记本中用 IE 浏览器打开 则弹出提示 if (!! window.ActiveXObject || 'ActiveXObject' in window) { alert('balabala。。。') } else { const c = document.querySelector('body') c.style.zoom = 1 / devicePixelRatio// 修改页面的缩放比例 } } } } }
这种实现方式相当于在页面创建后就给他 bind 了 resize 的方法,每次变更时自动调用调整页面缩放比例的方法 resizeFun, 这样就解决了缩放浏览器或者页面时页面内容不会错乱问题。