【问题标题】:Why window.matchMedia is called when I print the page in Chrome?为什么我在 Chrome 中打印页面时会调用 window.matchMedia?
【发布时间】:2021-12-12 03:16:21
【问题描述】:

我发现当我有一个基于宽度的 matchMedia 查询在页面中侦听时,它会在我打印时被调用。

这是一个更全面的sn-p:

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no,viewport-fit=cover" />
  </head>

  <body>
    <div>Open me in chrome, look at the console and print the page</div>
    <script>
      const mediaQuery = window.matchMedia('only screen and (min-width: 768px)')
      mediaQuery.addEventListener('change', () => {
        console.log('change width event', { innerWidth: window.innerWidth, outerWidth: window.outerWidth })
      })
    </script>
  </body>
</html>

在我的控制台中,我可以看到window.innerWidth 在打印时的值为 555,然后在此之后使用我的窗口的正确值(大于 555)调用 mediaQuery。

为什么会发生这种情况,我们如何禁用它?

【问题讨论】:

    标签: javascript media-queries


    【解决方案1】:

    这可能是因为only screenprint 正好相反。 当您打印页面时,查询将不再适用,并且会调用 matchMedia 事件

    只需删除 only screen 可能可以解决您的问题

    编辑:另一个想法可能是使用window.onberforeprint (window.addEventListener("beforeprint", function(event) { ... });) 捕获打印请求并设置一个布尔值,以便您现在打印页面

    【讨论】:

    • 非常感谢,我试过没有only screen,我也遇到了同样的问题。但是对于使用 beforeprint 事件的想法 +1,我不知道。非常感谢。
    【解决方案2】:

    看来,Chrome/Webkit 为打印预览重新加载页面是有道理的。
    为什么会两次触发 Event 我不能说(一次印刷一次未印刷),网上有很多相互矛盾的文章。我认为这与在预览和普通浏览器窗口之间切换上下文有关,但无论如何这里是matchMedia 的有效解决方案。

    免责声明:这有点老套/冗长,但有效。

    警告/信息:有一个边缘情况,当您关闭打印窗口太快/在正确的第二秒,第二个事件不会触发。并且因此将忽略下一个正常事件。为了解决这个问题,还可以添加带有setTimeout 语句的行,这会重置_ignoreNext 属性/变量。 (因为已经很长了,所以没有写在代码里)

    <!DOCTYPE html>
    <html>
      <head>
        <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no,viewport-fit=cover" />
      </head>
    
      <body>
        <div>Open me in chrome, look at the console and print the page</div>
        <script>
          const mediaQuery = window.matchMedia('(only screen and (min-width: 768px))');
          mediaQuery.addEventListener('change', () => {
                // check if the current state is for media Query "print"
                let matchtesPrint = window.matchMedia('print').matches;
                // mq._ignoreNext is a helper Variable, to catch the second Event triggered
                if(mq._ignoreNext && !matchtesPrint){
                    // reset everything to "normal"
                    mq._ignoreNext = false;
                } else if(matchtesPrint){
                    // if in print mode set helper variable, so that second event can be skipped
                    mq._ignoreNext = true;
                } else {
                    // normal mediaMatch
                    console.log('change width event', { innerWidth: window.innerWidth, outerWidth: window.outerWidth });
                }
          })
        </script>
      </body>
    </html>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-12
      • 2017-04-30
      • 2018-09-21
      • 2019-01-31
      • 2016-12-05
      • 1970-01-01
      • 1970-01-01
      • 2020-05-04
      相关资源
      最近更新 更多