6

我正在尝试编写一些 javascript 来更改在某些浏览器断点处保存在 JS 配置对象中的一些值。

我已将 window.matchmedia 测试存储在 config 对象中,然后循环遍历该对象的键以向每个测试添加事件侦听器,如下所示:

Object.keys(config.mediaQueries).map((key) =>{
     config.mediaQueries[key].addListener(function(){
         console.log("breakpoint change");
     });
});

https://codepen.io/decodedcreative/pen/YQpNVO

但是,当浏览器调整大小并且这些侦听器回调函数运行时,它们似乎运行了两次。在控制台打开的情况下检查上面的 CodePen,你就会明白我的意思了。

有谁知道我在这里做错了什么?

4

4 回答 4

6

要回答您的直接问题,您没有做错任何事情。JS 正在做它应该做的事情。

trld触发了 2 个事件,但只有一个包含匹配的媒体查询。

发生的情况是,当浏览器遇到断点时,会记录 2 个事件。例如,让我们考虑浏览器从 1250px 调整到 1150px 的情况。当窗口的宽度达到 1199px 时,您的函数:

Object.keys(config.mediaQueries).map((key) =>{
  config.mediaQueries[key].addListener(function(event){
    console.log("breakpoint change");
  });
});

将记录 2 个事件。如果您深入研究并记录事件:

Object.keys(config.mediaQueries).map((key) =>{
  config.mediaQueries[key].addListener(function(event){
    console.log(event);
  });
});

您将看到有关媒体查询的更多信息。我已经将事件对象归结为下面的重要道具。

// First event
matches: true
media: "(max-width: 1199px) and (min-width: 992px)"

// Second event
matches: false
media: "(min-width: 1200px)"

这里发生的是 2 个事件被记录,但只有一个事件包含匹配的查询。

因此,如果我们想改进您的日志记录脚本,您可以检查该matches属性:

Object.keys(config.mediaQueries).map((key) =>{
  config.mediaQueries[key].addListener(function(event){
    if (event.matches) { 
      console.log(event);
    }
  });
});

通过这个小改动,只会记录匹配的媒体查询。

于 2017-07-01T19:36:16.900 回答
2

如果您更改console.log("breakpoint change");console.log(key, "breakpoint change");,您将看到手动调整浏览器窗口大小时触发了xs和查询。s

如果您只希望回调在一个时间窗口内触发一次,则需要限制事件或以其他方式实现行为。

编辑:Tomasz BubałaBrett DeWoody的回答都指出该event.matches属性是解决此问题的正确且更.matchMedia具体的解决方案。

于 2017-07-01T19:00:27.820 回答
1

似乎事件是在调整大小之前和调整大小之后触发的。如果要在更改后立即记录“断点”更改,请添加 if 语句。

编辑:Noah Freitas 可能在调整大小时触发 2 个键的事件是正确的。如果它与键匹配,e.matches 仍然返回 true,因此它应该可以正常工作

    function(e) {
      if(e.matches) {
        console.log("breakpoint change");
      }
    }
于 2017-07-01T19:00:06.417 回答
0

不确定,如果这已经是完整的答案。但你是对的。回调触发了两次 - 用于两个不同的键。

我修改了您的示例,因此它输出key

Object.keys(config.mediaQueries).map((key) =>{
    console.log("register key: '" + key + "'");
    config.mediaQueries[key].addListener(function(){
        console.log("breakpoint change key:'" + key + "'");
    });
});

结果日志输出总是产生两行:

breakpoint change key:'m'
breakpoint change key:'l'

或减小宽度:

breakpoint change key:'s'
breakpoint change key:'m'
于 2017-07-01T19:02:51.930 回答