Window.matchmedia监听器触发两次

Jam*_*ell 5 javascript ecmascript-6 matchmedia

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

我已经在配置对象中存储了window.matchmedia测试,然后我循环遍历这个对象的键,为每个测试添加一个事件监听器,如下所示:

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

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

但是,当调整浏览器大小并运行这些侦听器回调函数时,它们似乎运行两次.在您的控制台打开的情况下检查上面的CodePen,您将看到我的意思.

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

Bre*_*ody 5

To answer your direct question, you haven't done anything wrong. And the JS is doing exactly what it's supposed to do.

trld There are 2 events firing but only one contains a matching media query.

What's happening is that when the browser hits a breakpoint there are 2 events being logged. As an example, let's consider the case of when the browser is being resized from 1250px down to 1150px. When the window hits 1199px in width your function:

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

will log 2 events. If you dive into this deeper and log the events with:

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

you'll see some more information on the media queries. I've boiled the event object down to the important props below.

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

// Second event
matches: false
media: "(min-width: 1200px)"
Run Code Online (Sandbox Code Playgroud)

What's happening here is 2 events are being logged, but only one of the events contains the matching query.

So, if we wanted to improve your script for logging, you could check the matches property:

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

With this small change only the matching media query will be logged.