Jquery resize () вызывает мерцание экрана и смещение div

Предыстория:

Я пытаюсь создать систему, которая позволяет прокручивать карту с помощью прокрутки мыши вверх и прокрутки мыши вниз, например:

 -------
|       |
|   1   |
|       |
 -------
 -------    -------   -------   -------
|       |  |       | |       | |       |
|   2   |  |   3   | |   4   | |   5   |
|       |  |       | |       | |       |
 -------    -------   -------   -------
                                -------
                               |       |
                               |   6   |
                               |       |
                                -------

Каждое из вышеперечисленных полей сбрасывается в javascript, чтобы соответствовать высоте и ширине браузера. Когда вы прокручиваете указатель мыши вверх и вниз, браузер переместится в такое же положение на карте, начиная с div 1, затем 2 и так далее. Это позиционирование устанавливается с помощью моей функции прокрутки, которая отслеживает прокрутки мыши и добавляет соответствующие отступы вверху и маржу слева, чтобы создать иллюзию карты выше.

Вот код к нему:

http://codepen.io/lorenzoi/pen/mxejJ

И вот к нему javascript:

$(function(){

    $(window).on('resize', function(){
        var $divs = $('.vertical, .horizontal > div'),
        ww =  $(this).width(),
        wh =  $(this).height();

        $divs.css({
            height : wh,
            width : ww
        });

        $('.horizontal').each(function(){
            var $container = $(this),
            nbChildren = $container.children().length;
            posY = $container.offset().top,


            $container.css({
                height: ww*(nbChildren-1) + wh,
                width: ww*(nbChildren)
            });
        });
    }).trigger('resize');

    $(window).on('scroll', function(){
        var wh = $(window).height(),
        scroolTop = $(window).scrollTop();

        $('.horizontal').each(function(){
            var $container = $(this),
            posY = $container.offset().top,
            height = $container.height(),
            nbChildren = $container.children().length,
            marginMax = $container.width()/nbChildren*(nbChildren-1),
            marginL = scroolTop - posY;

            if(marginL<0) marginL = 0;
            else if (marginL>marginMax) marginL = marginMax;
            $container.css('marginLeft', -marginL);
            $container.css('paddingTop', marginL);
        });
    }).trigger('scroll');

});

Проблема:

Изменение размера окна создает странное смещение блока div, которое устраняется при вызове функции прокрутки для блоков 2–5. При изменении размера в этих блоках кажется, что они смещаются сами по себе, а затем фиксируются только при вызове функции прокрутки.

.trigger ('изменить размер'); всегда надо называть, да? Я не знаю, почему он вызывается только при выполнении функции прокрутки.

Как это исправить?


person lorenzoid    schedule 19.04.2013    source источник
comment
debounce - это, вероятно, то, что вам нужно после github.com/cowboy/jquery-throttle-debounce   -  person epascarello    schedule 19.04.2013
comment
Событие изменения размера вызывается правильно. Проблема в вашем коде, а не в отправке.   -  person diego nunes    schedule 29.04.2013


Ответы (3)


Достаточно использовать таймер:

$(function(){
    var timeoutResize;

    $(window).on('resize', function(){
        clearTimeout(timeoutResize);
           timeoutResize = setTimeout(function(){
           var $divs = $('.vertical, .horizontal > div'),
           ww =  $(this).width(),
           wh =  $(this).height();

           $divs.css({
               height : wh,
               width : ww
           });

           $('.horizontal').each(function(){
               var $container = $(this),
               nbChildren = $container.children().length;
               posY = $container.offset().top,


               $container.css({
                   height: ww*(nbChildren-1) + wh,
                   width: ww*(nbChildren)
               });
           });
       },100);
    }).trigger('resize');

    ...

});
person A. Wolff    schedule 23.04.2013

. . Вы должны учитывать, что всякий раз, когда пользователь изменяет размер окна по вертикали, это влияет на позицию прокрутки, и это также должно влиять на фоновую прокрутку (поскольку она основана на текущей позиции прокрутки).

. . Самым простым решением будет просто вызвать $(window).trigger('scroll'); в конце кода обработчика изменения размера, чтобы оставить его СУХИМ. Я внес это изменение в мою вилку CodePen. Проверить это.

person diego nunes    schedule 29.04.2013

Если у вас есть обработчик событий, который запускается слишком часто, вы можете задросселировать его следующим образом:

function throttle(ms, fn) {
    var allow = true;
    function enable() {
        allow = true;
    }
    return function(e) {
        if (allow) {
            allow = false;
            setTimeout(enable, ms);
            fn.call(this, e);
        }
    }
}

Затем передайте свой обработчик throttle при его назначении. Он вернет функцию, которая будет запускаться не чаще одного раза в n миллисекунды в зависимости от первого предоставленного вами аргумента.

$(window).resize(throttle(100, function(e) {
    // do heavy work
}));
person Community    schedule 19.04.2013
comment
Проблема не имеет абсолютно никакого отношения к слишком частым событиям. Вы прочитали вопрос? - person diego nunes; 29.04.2013
comment
@DiegoNunes: Вопрос был обновлен спустя много времени после того, как я ответил. Первоначальный вопрос звучал так: Как я могу оптимизировать $ (window) .resize (), чтобы не было постоянного пересчета, когда пользователь прокручивает мою карту div? - person ; 29.04.2013
comment
О, я вижу. Тогда приятно, что это отметили здесь, в комментариях :) - person diego nunes; 29.04.2013