我动态创建了在不同窗口大小下反应不同的元素。这些大小是动态的,可以通过用户的数组传入。例如,像{500 : 3, 300: 1}
这样的对象数组将以500px显示3个项目,以300px显示1个项目。我在init上创建了这些监听器:
var sizesArray = {500 : 3, 300: 1};
var numItems = shownItems;
$.each(sizesArray, function(key, value) {
$(window).on("resize", elem, function () {
if ($(window).width() <= key) {
shownItems = value;
} else {
shownItems = numItems;
}
});
})
所以,基本上这就是说列表中的每一对都创建一个调整大小的侦听器。当窗口低于给定大小时,更改显示为该值的项目数。如果不低于该尺寸,则返回默认尺寸。
当数组中只有一个键/值时,这可以正常工作,但是当有两个键/值时,它会变得混乱。使用数组{500 : 3, 300: 1}
当窗口低于500时,它会转到预期的3个项目,但是当窗口低于300px时,两个事件都会被触发,它仍然停留在3个项目而不是预期的1个。
我尝试添加stopPropogation()
,stopImmediatePropogation()
和preventDefault()
,但似乎都没有效果。有更好的解决方案吗?
答案 0 :(得分:0)
您只能使用一个resize
事件,然后迭代该对象。当您迭代对象时,只要在获得true
值时就中断循环,这将阻止其他检查:
var sizesArray = [{ size: 300, value: 1 }, { size: 500, value: 3}]; // use an array that contains size objects listed from the smallest size to the largest to avoid browsers differences when iterating objects
var numItems = shownItems;
$(window).on("resize", function () {
var width = $(window).width();
shownItems = numItems; // reset the number of shown items
$.each(sizesArray, function (index, sizeObj) { // iterate sizes array
if (width <= sizeObj.size) { // if width <= key return false - break the loop, so the other checks won't occur
shownItems = sizeObj.value;
return false;
}
});
});
该示例使用window.matchMedia。检查此fiddle右下方窗格的控制台以查看更改:
var sizesArray = [{ // should be sorted from smallest to largest
size: 300,
value: 1
}, {
size: 500,
value: 3
}];
var lastQueryIndex = sizesArray.length - 1; // cache the index of the last query
var numItems = shownItems;
sizesArray.forEach(function (query, index) {
var match = window.matchMedia("(max-width: " + query.size + "px)"); // create the queries
match.addListener(function (mediaQueryListEvent) { // check match on resize
console.log(query.size, match.matches);
mediaQueryListEvent.matches && updateState(query.value);
index === lastQueryIndex && !mediaQueryListEvent.matches && updateState(numItems); // for the last query, check if bigger to restore default
});
console.log(query.size, match.matches);
match.matches && updateState(query.value); // update onload
});
function updateState(value) {
shownItems = value;
console.log(shownItems);
}