【问题标题】:How can I force a matching window.matchMedia to execute on page load?如何强制匹配的 window.matchMedia 在页面加载时执行?
【发布时间】:2020-09-21 21:40:58
【问题描述】:

我注意到 css 媒体查询定义和 javascript window.matchMedia 媒体查询定义之间的区别:

css 规则最初应用于加载的页面。

javascript中定义的规则不会在页面加载后执行,而是在输入新条件后执行。

一个例子:

我有两个具有等效媒体查询定义的不同页面,第一个在 css 中定义,第二个在 javascript 中定义:

css 版本(在样式元素中定义):

@media (min-width: 401px) and (max-width: 600px) { body {background-color: red; } }
@media (min-width: 601px) and (max-width: 800px) { body {background-color: blue; } }

javascript 版本(全局定义或在正文加载后调用的函数中定义):

window.matchMedia("(min-width: 401px) and (max-width: 600px)")
.addListener(function(e) {
  if (e.matches) {
    document.body.style.background = "red";
  }
});

window.matchMedia("(min-width: 601px) and (max-width: 800px)")
.addListener(function(e) {
  if (e.matches) {
    document.body.style.background = "blue";
  }
});

当我加载一个页面并且窗口是 700 像素宽时

  • css 版本页面为蓝色
  • javascript 版本是白色的,只有在满足新条件后才会更改其状态,即窗口大小低于 601 像素。

如何强制匹配的 window.matchMedia 在页面加载时执行?

【问题讨论】:

  • 我知道 window.onresize 和 body onload,我知道我可以使用它们来解决我的问题。但我认为这是没有必要的。我相信 window.matchMedia 的行为与 css 解决方案相同。我认为使用回调函数注册一次查询就足够了。

标签: javascript media-queries


【解决方案1】:

要在加载时触发matchMedia,您可以这样做(使用稍微更干净 的代码库)。

堆栈sn-p

<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <script>
      document.addEventListener("DOMContentLoaded", function(e) {
      
        // medias (as an array to make it a little easier to manage)
        var mqls = [
          window.matchMedia("(max-width: 400px)"),
          window.matchMedia("(min-width: 401px) and (max-width: 600px)"),
          window.matchMedia("(min-width: 601px) and (max-width: 800px)"),
          window.matchMedia("(min-width: 801px)")
        ]
        
        // event listeners
        for (var i=0; i<mqls.length; i++){
          mqls[i].addListener(mqh)
        }
        
        // matches methods
        function mqh(){
          if (mqls[0].matches) {
            console.log("CALLBACK (max-width: 400px)");
            document.body.style.background = "green";
          } else if (mqls[1].matches) {
            console.log("CALLBACK (max-width: 600px)");
            document.body.style.background = "red";
          } else if (mqls[2].matches) {
            console.log("CALLBACK (max-width: 800px)");
            document.body.style.background = "blue";
          } else if (mqls[3].matches) {
            console.log("CALLBACK (min-width: 801px)");        
            document.body.style.background = "gray";
          }
          console.log("window.innerWidth: " + window.innerWidth);
        }

        // call once on load
        mqh();
      });
      
    </script>
  </head>

  <body>
  </body>

</html>

组织。来源:http://www.javascriptkit.com/javatutors/matchmediamultiple.shtml

【讨论】:

  • 感谢您的回答。在我的回答中看起来像相同的方法。
  • @NathanPerigreth 主要区别是我不需要resize 事件
  • 你是对的。但这意味着您必须 1) 显式调用页面加载的匹配函数,并且您必须 2) 将匹配函数绑定为回调函数,以防页面调整大小。这是更好的解决方案吗?
  • @NathanPerigreth 如果您发布代码是为了您自己的建议,我要么坚持我的建议,要么将其删除并支持您的建议:)
  • 根据您的经验,您更喜欢哪种解决方案?与 css 解决方案相比,我发现两者都有点笨拙(当需要 javascript 功能时当然不能使用)。
【解决方案2】:

页面加载时不会调用绑定到 window.matchMedia 的回调函数。

解决问题的方法是:

  • 定义一个函数,通过if(window.matchMedia("...").matches){显式检查媒体查询
  • 通过&lt;body onload在页面加载时调用该函数
  • 通过window.onresize在调整大小时调用该函数

【讨论】:

  • 因为这也是一个可行的选择,加 1
【解决方案3】:

我今天遇到了同样的问题,我使用了受Nathan启发的以下解决方案:

const gate = 800

function listener(
  matches,
) {
  document.getElementById('tag').innerHTML = matches ? 'wider' : 'narrower'
}

window.onload=() => {
  const match = window.matchMedia(`(min-width: ${gate}px)`)
  match.addListener(e => listener(e.matches))
  listener(match.matches)
}
<h1>
  This window is 
  <span id='tag'></span>
  than 800px
</h1>

核心概念是使用MediaQueryList.matches 作为参数传递一次监听器函数。

如果有人试图通过框架实现这一点,请记住在组件挂载事件期间注册并触发侦听器。

【讨论】:

  • 这应该是最佳答案
  • @ZachSaucier -- 如果您还解释了为什么它应该是最佳答案,那么用户将有更实质性的东西来考虑投票。另请注意,OP 有几个媒体查询要设置,我看不出这比我在回答中建议的更简单(更好)。
猜你喜欢
  • 2017-01-12
  • 1970-01-01
  • 2016-02-11
  • 2013-03-05
  • 1970-01-01
  • 1970-01-01
  • 2012-03-26
  • 1970-01-01
  • 2014-08-08
相关资源
最近更新 更多