我正在遍历包含多个元素的对象,每个元素都包含多个媒体查询。
在循环中,我动态调用enquire.js .register()
来执行匹配操作。这最初工作,但在循环之外,并且在调整浏览器大小后,匹配不再起作用,因为循环中使用的变量已从循环增加到其高测试值。
在代码中解释可能更容易!
这是images
对象:
var images = [
{
"selector":"[data-id=\"0\"]",
"breakpoints":[
{
"mediaquery":"(max-width: 31.25em) ",
"src":"image-0-small.jpg"
},
{
"mediaquery":"(min-width: 31.3125em) and (max-width: 46.25em) ",
"src":"image-0-medium.jpg"
},
{
"mediaquery":"(min-width: 46.3125em) ",
"src":"image-0-large.jpg"
}
]
},
{
"selector":"[data-id=\"1\"]",
"breakpoints":[
{
"mediaquery":"(max-width: 31.25em) ",
"src":"image-1-small.jpg"
},
{
"mediaquery":"(min-width: 31.3125em) and (max-width: 46.25em) ",
"src":"image-1-medium.jpg"
},
{
"mediaquery":"(min-width: 46.3125em) ",
"src":"image-1-large.jpg"
}
]
},
{
"selector":"[data-id=\"2\"]",
"breakpoints":[
{
"mediaquery":"(max-width: 31.25em) ",
"src":"image-2-small.jpg"
},
{
"mediaquery":"(min-width: 31.3125em) and (max-width: 46.25em) ",
"src":"image-2-medium.jpg"
},
{
"mediaquery":"(min-width: 46.3125em) ",
"src":"image-2-large.jpg"
}
]
}
];
这是循环:
for (var x=0; x < images.length; x++) {
for (var y=0; y < images[x]['breakpoints'].length; y++) {
enquire.register(images[x]['breakpoints'][y]['mediaquery'], function () {
// x and y unfortuntaley equal 3 & 3 after the loop, so how do I maintain them from inside the match?
// Interestingly, Firefox doesn't seem attempt to fire matches more than once. Chrome and IE 11 do, which is where I found the error that images[x] is undefined
console.log('match-index', x, y);
console.log('match-images', images);
console.log('match-mediaquery', images[x]['breakpoints'][y]['mediaquery']);
});
}
}
images[x]
未定义,因为x = 3
。如何让x
和y
与最近在match
es中传入的内容相等?
答案 0 :(得分:1)
可变范围保持在功能级别。因此,您必须找到一种方法在每次迭代时创建变量的副本,并将该副本传递给注册函数。
这样做的一种方法是创建一个立即执行的函数表达式,该表达式返回最终由register()
执行的函数。
它看起来像这样:
(function(innerX, innerY) {
return function() {
// use innerX and innerY here
};
}(x, y))
这种方法的工作方式是立即执行的函数表达式为它返回的函数创建一个闭包,它引用了x和y副本 - innerX和innerY。
答案 1 :(得分:1)
奇妙的@WickyNilliams教会了我关于闭包的知识,并提供了以下工作代码:
function registerWithEnquire(x, y) {
enquire.register(swapImages[x]['breakpoints'][y]['mediaquery'], function () {
// I want to set the src of the relevant cloned image to its corresponding src property in the swapImages object with:
//document.querySelector(swapImages[x]['selector']).src = swapImages[x]['breakpoints'][y]['src'];
// x and y unfortuntaley equal 5 & 3 after the loop, so how do I maintain them from inside the match?
// Interestingly, Firefox doesn't seem attempt to fire matches more than once. Chrome and IE 11 do, which is where I found the error that swapImages[x] is undefined
console.log('match-index', x, y);
console.log('match-swapImages', swapImages);
console.log('match-mediiquery', swapImages[x]['breakpoints'][y]['mediaquery']);
});
}
for (var x=0; x < swapImages.length; x++) {
console.group(x);
console.log(swapImages[x]['selector']);
for (var y=0; y < swapImages[x]['breakpoints'].length; y++) {
console.log(swapImages[x]['breakpoints'][y]['mediaquery']);
registerWithEnquire(x, y);
}
console.groupEnd();
}
console.log(x, y);