我正在尝试编写一些javascript,它将更改某些浏览器断点处JS配置对象中保存的某些值。
我已经在配置对象中存储了window.matchmedia测试,然后我循环遍历这个对象的键,为每个测试添加一个事件监听器,如下所示:
Object.keys(config.mediaQueries).map((key) =>{
config.mediaQueries[key].addListener(function(){
console.log("breakpoint change");
});
});
https://codepen.io/decodedcreative/pen/YQpNVO
但是,当调整浏览器大小并运行这些侦听器回调函数时,它们似乎运行了两次。在您的控制台打开的情况下检查上面的CodePen,您将看到我的意思。
有谁知道我在这里做错了什么?
答案 0 :(得分:4)
要回答你的直接问题,你没有做错任何事。 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);
}
});
});
通过这个小的更改,只会记录匹配的媒体查询。
答案 1 :(得分:2)
如果您将console.log("breakpoint change");
更改为console.log(key, "breakpoint change");
,则会在手动调整浏览器窗口大小时看到xs
和s
查询都被触发。< / p>
如果您只希望在时间窗口内触发一次回调,则需要限制事件或以其他方式实现行为。
修改:Tomasz Bubała和Brett DeWoody的答案都指向event.matches
属性作为此问题的正确解决方案.matchMedia
。
答案 2 :(得分:1)
似乎事件在调整大小之前和调整大小之后就开始了。如果要在更改后立即更改“断点”,请添加if语句。
编辑:Noah Freitas在调整大小时触发2个键的事件可能是正确的。如果e.matches与键匹配,则返回true,因此它应该可以正常工作
function(e) {
if(e.matches) {
console.log("breakpoint change");
}
}
答案 3 :(得分: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'