Window.Resize阻止传播到更高的断点

时间:2015-09-05 21:32:35

标签: javascript jquery resize

我动态创建了在不同窗口大小下反应不同的元素。这些大小是动态的,可以通过用户的数组传入。例如,像{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(),但似乎都没有效果。有更好的解决方案吗?

1 个答案:

答案 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);
}