热搜:fiddler git ip ios 代理
历史搜索

Vue项目前端适配笔记本缩放125%,150%时导致页面错乱的解决方法

游客2024-09-25 07:30:02

前言

叮咚~,测试小姐姐发消息说她的 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, 这样就解决了缩放浏览器或者页面时页面内容不会错乱问题。