2015-07-23 7 views
0

Я вызываю код, когда мое окно полностью изменено с помощью события window.resize() и с помощью ссылки this. он сработал, но проблема в том, что он будет медленным, поскольку вы выполняете повторный размер более 3 раз. Так как вы увеличиваете количество повторных размеров, страница становится медленнее и медленнее.Window.resize() замедляется по мере увеличения размера размера

Мой код, как показано ниже,

$(window).bind('resize', function(e) { 
    window.resizeEvt; 
    $(window).resize(function() { 
     clearTimeout(window.resizeEvt); 
     window.resizeEvt = setTimeout(function() { 
      //code to do after window is resized 
     }, 250); 
    }); 
}); 

Может ли один помочь мне определить, почему его замедление?

+0

Замените '// код, который нужно сделать после изменения окна ', на' console.log («a»); 'и проверьте, сколько вы создаете' setTimeout(); ' – Justinas

+0

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

+0

Это может быть причиной? как в этой ссылке .. http://stackoverflow.com/questions/4211046/why-do-multiple-settimeout-calls-cause-so-much-lag –

ответ

1

Событие изменения размера окна запускается каждый раз, когда размер браузера изменяется, для каждого пикселя и не только один раз; событие не задерживается. Кроме того, вы должны вручную выполнить событие изменения размера ... пока вы находитесь в своем событии изменения размера. Вам не нужно звонить $(window).resize! Вам нужно только связать событие один раз (и .bind устарел, в пользу .on).

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

/** 
    Author: [email protected] 
    License: MIT 

    Return a copy of the function fn that can be called multiple times. 
    The function fn will actually be called if 1) a certain amount of 
    time elapsed after the last call, or 2) a certain number of repetitive 
    calls have been made. 

    The function fn will be invoked with the last arguments sent through 
    the returned proxy function. 

    Options are : 

    - delay {Numeric} the number of ms before satisfying the first condition 
    - stack {Numeric} the number of repetitive calls before satisfying the second condition 

    NOTE : these conditions are ORed, meaning that fn will be invoked if either 
     condition 1) or 2) is met. 

    @param {Function} fn  the function to proxy 
    @param {Object} options the key-pair of options 
    @param {any} ctx   a context to bind fn to when calling 
    @return {Function}   a proxy function. 
*/ 
function asyncProxy(fn, options, ctx) { 
    var timer = null; 
    var counter = 0; 
    var _call = function (args) { 
    counter = 0; 

    fn.apply(ctx, args); 
    }; 

    ctx = ctx || window; 
    options = $.extend({ 
    delay: 0, 
    stack: Infinity 
    }, options); 

    return function() { 
    counter++; 

    // prevent calling the delayed function multiple times 
    if (timer) { 
     clearTimeout(timer); 
     timer = null; 
    } 

    if (counter >= options.stack) { 
     _call(arguments); 
    } else { 
     var args = arguments; 

     timer = setTimeout(function() { 
     timer = null; 
     _call(args); 
     }, options.delay); 
    } 
    }; 
} 

И вы используете его как этот

var processWindowResize = asyncProxy(function (event) { 

    // *** Your code goes here *** 

}, { 
    delay: 250 
}); 

$(window).on('resize', processWindowResize); 
0

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

Что вам нужно сделать, это просто, в конце концов, когда окно закончил повторное проклейки:

$(window).off("resize", resizeEvt); 

этот путь вы очищаете событие, превращая его каждый раз, когда событие выполняется, так он не замедлит вашу веб-страницу.

+0

'resizeEvt' - это номер, идентифицирующий' setTimeout', это не событие. И когда вы выключаете событие изменения размера, при следующем изменении размера окна ничего не произойдет. – Justinas

+0

Я добавил $ (окно) .off ("resize", resizeEvt); в конце, но никаких улучшений. –

0

Проблема с любым кодом на основе тайм-аута в том, что если пользователь изменяет размер окна медленно, то он может стрелять несколько раз для изменения размера (который включает в себя этот код) - если это просто случай обновления дисплея, то мое предпочтение использовать requestAnimationFrame, чтобы убедиться, что он чист, как это возможно для этого обновления -

var resizing = false, 
    processingResize = false; 

function processResize() { 
    if (resizing) { 
     resizing = false; 
     window.requestAnimationFrame(processResize); 
    } else { 
     processingResize = false; 
     // Do stuff here 
    } 
} 

$(window).on("resize", function(event) { 
    if (!resizing && event.target === window) { 
     resizing = true; 
     if (!processingResize) { 
      processingResize = true; 
      window.requestAnimationFrame(processResize); 
     } 
    } 
}); 

Gen У меня на самом деле есть оболочка для rAF, которая проверяет document.hidden и использует setTimeout, когда страница не видна, - но это не относится к простому использованию, так как она будет вызываться один раз, когда страница снова станет видимой, и любое изменение размера может произойти тогда ,

Если вы пытаетесь обнаружить, когда пользователь полностью закончил изменение размера, то нет абсолютного метода, но включение событий mousemove будет более точно воспринимать его.

Смежные вопросы