写在开头
除非客户必须要这种,否则笔者非常不推荐做这样的适配。目前这种适配方式可能导致在非100%分辨率时,产生例如echarts点击事件、elementPlus滑块点击等出现错位等情况。
效果展示
100%正常情况:
500%默认情况:
500%调整后:
主要代码
新建rem.js文件
class DevicePixelRatio {
constructor() {
// this.flag = false;
}
// 获取系统类型
_getSystem() {
// let flag = false;
var agent = navigator.userAgent.toLowerCase();
// var isMac = /macintosh|mac os x/i.test(navigator.userAgent);
// if(isMac) {
// return false;
// }
// 现只针对windows处理,其它系统暂无该情况,如有,继续在此添加
if (agent.indexOf('windows') >= 0) {
return true;
}
}
// 获取页面缩放比例
// _getDevicePixelRatio() {
// let t = this;
// }
// 监听方法兼容写法
_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() {
// 页面devicePixelRatio(设备像素比例)变化后,计算页面body标签zoom修改其大小,来抵消devicePixelRatio带来的变化。
let zoom_val = 1 / window.devicePixelRatio;
document.getElementsByTagName('body')[0].style.setProperty('zoom', zoom_val);
// 适配火狐浏览器
if (navigator.userAgent.indexOf('Firefox') >= 0) {
document.documentElement.style.MozTransform = `scale(${zoom_val})`;
document.documentElement.style.MozTransformOrigin = '0 0';
}
}
// 监听页面缩放
_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/rem';
const zoomRatio = ref(100); // 给全局设置的缩放百分比
const screenWidth = window.screen.width * window.devicePixelRatio; // 获取设备像素
onMounted(() => {
if (screenWidth <= 1920) {
detectZoom();
window.addEventListener('resize', detectZoom); // 计算缩放百分比
new DevicePixelRatio().init();
} else {
// 防止设备像素过高,无法通过放大查看页面细节
setDocumentStyle();
}
}
onBeforeUnmount(() => {
// 移除监听事件
if (screenWidth <= 1920) window.removeEventListener('resize', detectZoom);
});
function detectZoom() {
let ratio = 0,
screen: any = window.screen,
ua = navigator.userAgent.toLowerCase();
if (window.devicePixelRatio !== undefined) {
ratio = window.devicePixelRatio;
} else if (~ua.indexOf('msie')) {
if (screen.deviceXDPI && screen.logicalXDPI) {
ratio = screen.deviceXDPI / screen.logicalXDPI;
}
} else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
ratio = window.outerWidth / window.innerWidth;
}
// ratio就是获取到的百分比
// console.log(ratio);
zoomRatio.value = ratio * 100;
setDocumentStyle();
}
// 添加全局css变量
function setDocumentStyle() {
document.documentElement.style.setProperty('--onresize_height', zoomRatio.value + 'vh');
document.documentElement.style.setProperty('--onresize_width', zoomRatio.value + 'vw');
// 适配火狐浏览器
if (navigator.userAgent.indexOf('Firefox') >= 0)
document.documentElement.style.setProperty('width', zoomRatio.value + 'vw');
}
全局css样式调整:
.all{
height: var(--onresize_height); // 修改前:100vh
width: calc(var(--onresize_width) * 0.7); // 修改前:70vw
}
重点问题
- 缩放后把下面的一部分剪掉了,如果不想被剪掉就要获取缩放的百分比,然后设置给最外层的高度。
- 火狐浏览器不支持zoom,需要特殊处理。
- echarts点击事件会发生偏移(待解决)。
let body = document.getElementsByTagName('body');
body[0].style.setProperty('zoom', 1);
参考文档
链接: vue自适应浏览器缩放百分比
链接: vue调整页面适应不同百分比缩放
链接: javascript 获得分辨率