Событие изменения размера JavaScript запускается несколько раз при перетаскивании маркера изменения размера - PullRequest
21 голосов
/ 20 марта 2009

Я надеялся, что этот плагин jQuery будет работать, но это не так:

http://andowebsit.es/blog/noteslog.com/post/how-to-fix-the-resize-event-in-ie (старая ссылка была noteslog.com/post/how-to-fix-the-resize-event-in-ie).

Я добавил комментарий к его сайту, но они модерируются, поэтому вы можете его еще не увидеть.

Но, во всяком случае, позвольте мне объяснить мое желание. Я хочу, чтобы событие типа «изменение размера» запускалось, когда пользователь либо приостанавливает изменение размера, и / или завершает изменение размера, а не , в то время как пользователь активно перетаскивает маркер изменения размера окна браузера. У меня довольно сложная и трудоемкая функция OnResizeHandled, которую мне нужно запустить, но не запускать 100 раз только потому, что пользователь расширил окно на 100 пикселей, и событие было запущено для каждого пикселя движения. Полагаю, лучше всего было бы справиться с этим после того, как пользователь завершил изменение размера.

Ответы [ 7 ]

75 голосов
/ 21 марта 2009

Как насчет такого кода:

function resizeStuff() {
 //Time consuming resize stuff here
}
var TO = false;
$(window).resize(function(){
 if(TO !== false)
    clearTimeout(TO);
 TO = setTimeout(resizeStuff, 200); //200 is time in miliseconds
});

Это должно гарантировать, что функция изменяет размер только тогда, когда пользователь прекращает изменение размера.

9 голосов
/ 20 марта 2009

Заимствуйте некоторые идеи из параллельных решений для управления потоком событий, поступающих из браузера.

Например, когда вы впервые получаете событие изменения размера, установите флаг в значение true, указывающее, что пользователь в настоящее время изменяет размер. Установите тайм-аут для вызова фактического обработчика события изменения размера через 1 секунду. Затем, когда этот флаг имеет значение true, игнорируйте событие resize. Затем в фактическом обработчике, когда все сделано и исправлено, установите флаг обратно в false.

Таким образом, вы обрабатываете последнее событие только раз в секунду (или в другой период времени, в зависимости от ваших требований). Если пользователь делает паузу в середине изменения размера, он будет обрабатываться. Если пользователь закончил, он будет обрабатывать.

Возможно, это не подходит для вас, но есть много других способов использования блокировок, которые могут быть более полезными.

5 голосов
/ 16 июня 2011

У Пола Айриша есть отличный Дебадный плагин jQuery , который решает эту проблему.

2 голосов
/ 17 октября 2013

Если вы работаете с библиотеками, вам следует обратить внимание на подчеркивание, подчеркивание уже отвечает вашим потребностям и многое другое, что вы, вероятно, будете иметь в своих проектах.

Вот пример того, как работает debouncer:

// declare Listener function
var debouncerListener = _.debounce( function(e) {

    // all the actions you need to happen when this event fires

}, 300 ); // the amount of milliseconds that you want to wait before this function is called again

, затем просто вызовите функцию debouncer при изменении размера окна

window.addEventListener("resize", debouncerListener, false);

проверить все функции подчеркивания, доступные здесь http://underscorejs.org/

1 голос
/ 20 марта 2009

Как насчет установки времени ожидания, когда пользователь приостанавливает изменение размера? Сбросьте время ожидания при изменении размера или запустите обработчик события изменения размера, если время ожидания истекло.

0 голосов
/ 02 марта 2013

Несколько дней назад я продлил jQuery on -event-handler по умолчанию. Он прикрепляет функцию-обработчик события для одного или нескольких событий к выбранным элементам, если событие не было запущено в течение заданного интервала. Это полезно, если вы хотите запустить обратный вызов только после задержки, например, события изменения размера или в противном случае. https://github.com/yckart/jquery.unevent.js

;(function ($) {
    var methods = { on: $.fn.on, bind: $.fn.bind };
    $.each(methods, function(k){
        $.fn[k] = function () {
            var args = [].slice.call(arguments),
                delay = args.pop(),
                fn = args.pop(),
                timer;

            args.push(function () {
                var self = this,
                    arg = arguments;
                clearTimeout(timer);
                timer = setTimeout(function(){
                    fn.apply(self, [].slice.call(arg));
                }, delay);
            });

            return methods[k].apply(this, isNaN(delay) ? arguments : args);
        };
    });
}(jQuery));

Используйте его как любой другой обработчик событий on или bind, за исключением того, что вы можете передать дополнительный параметр как последний:

$(window).on('resize', function(e) {
    console.log(e.type + '-event was 200ms not triggered');
}, 200);

http://jsfiddle.net/ARTsinn/EqqHx/

0 голосов
/ 20 марта 2009

Поскольку он встроен в jQuery, вы не можете связать какое-либо событие onComplete с расширением и передать функцию, которая должна выполняться при его вызове?

Edit:

Когда пользователь начинает изменять размер окна, установите интервал, который просматривает размеры окна. Если размеры не изменились за заданный период времени, указанный в вашей спецификации, вы можете считать изменение размера окна «выполненным». В этом случае предпочтительной функцией javascript будет setInterval (), которая принимает два аргумента - функцию для вызова каждого тика и продолжительность каждого тика в миллисекундах.

Что касается того, как написать это конкретно в рамках jquery, ну, я не знаю достаточно о jquery, чтобы иметь возможность сказать вам это. Возможно, кто-то другой может помочь вам более конкретно, но в то же время вы можете рассмотреть возможность расширения расширения jquery, которое вы уже связали, с событием onComplete, которое работает так, как я только что описал.

...