【问题标题】:window.devicePixelRatio change listenerwindow.devicePixelRatio 更改监听器
【发布时间】:2022-04-07 05:52:33
【问题描述】:

window.devicePixelRatio 将返回 1 或 2,具体取决于我使用的是视网膜显示器还是标准显示器。如果我在两个监视器之间拖动窗口,这个属性将会改变。有什么方法可以在更改发生时触发侦听器?

【问题讨论】:

  • 我没有两个监视器来测试这个,但我认为resize 事件将在window.devicePixelRatio 更新时触发。
  • 刚试了,不火。
  • developer.mozilla.org Example 2: Monitoring screen resolution or zoom level changes 有一个很好的例子。
  • @user2570380 你不需要两台显示器来测试这个。只需打开例如Chrome DevTools → 切换设备工具栏(DevTools 左上角的手机/平板图标) → 三点菜单 → 添加设备像素比,然后随意更改 DPR。请注意,我在撰写本文时使用的是 Chrome 81。
  • @MichaelJohansen:它根本不会触发我(Windows),它目前似乎也有问题,请在 Chromium 跟踪器上查看此问题:bugs.chromium.org/p/chromium/issues/detail?id=1294293

标签: javascript retina


【解决方案1】:

您可以使用matchMedia 收听媒体查询,它会告诉您 devicePixelRatio 何时超过某个障碍(不幸的是,不能用于任意比例更改)。

例如:

window.matchMedia('screen and (min-resolution: 2dppx)')
    .addEventListener("change", function(e) {
      if (e.matches) {
        /* devicePixelRatio >= 2 */
      } else {
        /* devicePixelRatio < 2 */
      }
    });

当您在监视器之间拖动窗口以及插入或拔出外部非视网膜监视器(如果它导致窗口从视网膜移动到非视网膜屏幕或反之亦然)时,将调用侦听器。

IE10+ 支持window.matchMediaall other modern browsers

参考:https://code.google.com/p/chromium/issues/detail?id=123694MDN on min-resolution

【讨论】:

  • 现在已弃用。
  • 但是您可以使用 addEventListener 代替。 window.matchMedia('screen and (min-resolution: 2dppx)').addEventListener('change', listenerFunc, false);
  • 谢谢,我已经编辑了答案以反映新方法。
  • 这比其他答案差很多,因为它只允许固定边界
【解决方案2】:

互联网上的大多数(或全部?)答案只检测到特定的变化。通常,它们会检测值是 2 还是其他值。

问题可能在于 MediaQuery,因为它们只允许检查特定的硬编码值。

通过一些编程,可以动态创建媒体查询,检查当前值的变化。

let remove = null;

const updatePixelRatio = () => {
  if(remove != null) {
      remove();
  }
  let mqString = `(resolution: ${window.devicePixelRatio}dppx)`;
  let media = matchMedia(mqString);
  media.addListener(updatePixelRatio);
  remove = function() {media.removeListener(updatePixelRatio)};

  console.log("devicePixelRatio: " + window.devicePixelRatio);
}
updatePixelRatio();

【讨论】:

  • 聪明,但这不是在重复创建新的MediaQueryLists 吗?
  • 这很好。它可能不会导致泄漏,因为我删除了侦听器,这似乎是处理它的唯一方法。但这取决于浏览器如何实现此功能。
【解决方案3】:

我采用了 IMO 最佳答案(@Neil 提供)并使其更易于阅读:

function listenOnDevicePixelRatio() {
  function onChange() {
    console.log("devicePixelRatio changed: " + window.devicePixelRatio);
    listenOnDevicePixelRatio();
  }
  matchMedia(
    `(resolution: ${window.devicePixelRatio}dppx)`
  ).addEventListener("change", onChange, { once: true });
}
listenOnDevicePixelRatio();

不需要固定的边界或变量。

【讨论】:

    【解决方案4】:

    感谢@florian-kirmaier,这正是我要找的,如果您在事件侦听器中传递{once: true} 选项,则无需手动跟踪和删除事件侦听器。

    (function updatePixelRatio(){
    matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`)
    .addEventListener('change', updatePixelRatio, {once: true});
    console.log("devicePixelRatio: " + window.devicePixelRatio);
    })();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-22
      • 2010-09-08
      • 2011-07-16
      相关资源
      最近更新 更多