Window.matchmedia监听器发射两次
我想写一些JavaScript,它将改变某些浏览器断点处的JS配置对象内的某些值。Window.matchmedia监听器发射两次
我已存储的配置对象内的window.matchmedia测试,然后我遍历这个对象的关键事件侦听器添加到每个测试,像这样:
Object.keys(config.mediaQueries).map((key) =>{
config.mediaQueries[key].addListener(function(){
console.log("breakpoint change");
});
});
https://codepen.io/decodedcreative/pen/YQpNVO
然而当浏览器调整大小并且这些侦听器回调函数运行时,它们似乎运行两次。打开控制台检查上面的CodePen,你会明白我的意思。
有谁知道我在这里做错了吗?
要回答你的直接问题,你没有做错任何事。 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);
}
});
});
有了这个小变化只有匹配的媒体查询将被记录。
似乎事件正在调整大小之前和调整大小之后。如果要在更改后立即记录“断点”更改,请添加一条if语句。
编辑:诺亚弗雷塔斯可能是正确的事件触发2键调整大小。不过e.matches返回true,如果它是匹配的,因此如果您改变console.log("breakpoint change");
到console.log(key, "breakpoint change");
应该正常工作
function(e) {
if(e.matches) {
console.log("breakpoint change");
}
}
,你会看到,无论是xs
和s
查询被触发时,您手动调整浏览器窗口。
如果您只希望在一个时间窗口内触发一次回调,则需要调整事件或以其他方式实现行为。
编辑:Tomasz Bubała和Brett DeWoody的答案都指向event.matches
属性作为适当的和更多的.matchMedia
特定的解决方案来解决这个问题。
不确定,如果这已经是完整的答案。但你是对的。回调是两次触发 - 两个不同的键。
我修改您的例子,所以它输出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'
太棒了。谢谢你的帮助。 –