You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何区分显示器与浏览器缩放级别并识别浏览器100%缩放状态?

区分系统缩放与浏览器缩放,判断浏览器是否处于100%缩放状态

这个问题确实挺头疼的——window.devicePixelRatio把系统显示器缩放和浏览器自身缩放的数值叠在一起了,没法直接拆分。不过经过实践,还是有几种可靠的方案能帮你单独追踪浏览器的缩放级别,尤其是确认它是否处于100%状态:

方法一:基于初始基准值的比例对比(兼容全浏览器)

这个方法的核心是利用页面加载时的基准状态,后续通过对比比例来分离两种缩放:

  • 步骤1:记录初始基准
    页面首次加载时(假设此时浏览器处于100%缩放,且用户不会中途修改系统缩放),创建一个固定CSS尺寸的元素,然后获取它的实际物理宽度:
    // 页面加载完成时执行
    const baseElement = document.createElement('div');
    baseElement.style.width = '200px';
    baseElement.style.visibility = 'hidden';
    document.body.appendChild(baseElement);
    // 记录初始的物理宽度和devicePixelRatio
    const initialPhysicalWidth = baseElement.getBoundingClientRect().width;
    const initialDPR = window.devicePixelRatio;
    document.body.removeChild(baseElement);
    // 可以把这些值存在sessionStorage里,避免页面刷新后丢失
    sessionStorage.setItem('initialPhysicalWidth', initialPhysicalWidth.toString());
    sessionStorage.setItem('initialDPR', initialDPR.toString());
    
  • 步骤2:计算浏览器缩放比例
    之后需要检测时,重复创建相同尺寸的元素,获取当前物理宽度,结合初始值计算:
    function getBrowserScale() {
      const initialPW = parseFloat(sessionStorage.getItem('initialPhysicalWidth'));
      const initialDPR = parseFloat(sessionStorage.getItem('initialDPR'));
      if (!initialPW || !initialDPR) return 1;
    
      const tempElement = document.createElement('div');
      tempElement.style.width = '200px';
      tempElement.style.visibility = 'hidden';
      document.body.appendChild(tempElement);
      const currentPW = tempElement.getBoundingClientRect().width;
      document.body.removeChild(tempElement);
    
      // 系统缩放比例 = 初始DPR(因为当时浏览器是100%)
      const systemScale = initialDPR;
      // 当前总缩放比例 = 当前物理宽度 / CSS宽度
      const totalScale = currentPW / 200;
      // 浏览器缩放比例 = 总缩放 / 系统缩放
      return totalScale / systemScale;
    }
    
  • 判断100%缩放:考虑到浮点精度误差,用一个小范围判断即可:
    function isBrowserAt100Scale() {
      const scale = getBrowserScale();
      return Math.abs(scale - 1) < 0.01;
    }
    
    注意:如果用户中途修改了系统缩放,这个基准值会失效,需要重新校准。

方法二:利用视觉视口API(现代浏览器最优解)

现代浏览器提供了window.visualViewport API,它的scale属性直接返回浏览器自身的缩放比例,完全不受系统缩放的影响!比如系统缩放150%、浏览器100%时,visualViewport.scale就是1;浏览器缩放120%时,这个值就是1.2。

  • 示例代码:
    function getBrowserScale() {
      if ('visualViewport' in window) {
        return window.visualViewport.scale;
      }
      // 对不支持的浏览器,降级使用方法一的逻辑
      const initialPW = parseFloat(sessionStorage.getItem('initialPhysicalWidth'));
      const initialDPR = parseFloat(sessionStorage.getItem('initialDPR'));
      if (!initialPW || !initialDPR) return 1;
    
      const tempElement = document.createElement('div');
      tempElement.style.width = '200px';
      tempElement.style.visibility = 'hidden';
      document.body.appendChild(tempElement);
      const currentPW = tempElement.getBoundingClientRect().width;
      document.body.removeChild(tempElement);
    
      return (currentPW / 200) / initialDPR;
    }
    
    function isBrowserAt100Scale() {
      const scale = getBrowserScale();
      return Math.abs(scale - 1) < 0.01;
    }
    
    这个方法简洁可靠,但要注意兼容性:Chrome、Edge、Safari、Firefox 89+都支持,IE完全不支持。

方法三:监听视口尺寸变化(需排除窗口大小干扰)

你也可以通过对比初始视口宽度和当前视口宽度来计算,但要注意排除用户调整窗口大小的影响:

  • 页面加载时记录初始的window.innerWidth(浏览器100%缩放时的视觉视口宽度),后续监听resize事件时,结合screen.width / window.devicePixelRatio(系统缩放后的屏幕CSS宽度)来判断窗口是否真的调整了大小,再计算缩放比例。不过这个逻辑相对复杂,不如前两种方法实用。

总结

  • 如果需要兼容旧浏览器,优先用方法一;
  • 如果只面向现代浏览器,window.visualViewport.scale是最省心的方案;
  • 所有方法都要注意浮点精度问题,判断100%缩放时不要严格等于1,留一个±0.01的误差范围。

内容的提问来源于stack exchange,提问作者Gerrit Sedlaczek

火山引擎 最新活动