Использование функции throttle

183
27 июля 2018, 13:40

Подскажите, пожалуйста как правильно использовать функцию throttle, чтобы уменьшить количество вызовов функции обновления страницы. Пытался сделать что-то типа window.onresize = throttle(updateSize, 300); не помогло.

window.onload = function() { 
    svgDoc = document.getElementById("AutoId").contentDocument; 
    var timer = setInterval(anim, 100); 
    var timerPost = setInterval(setPost, 100); 
    initClick(); 
	updateSize(); 
} 
 
window.onresize = updateSize; 
 
function updateSize() { 
    vpW = document.getElementsByClassName('main')[0].clientWidth; 
    vpH = document.getElementsByClassName('main')[0].clientHeight; 
    //imgW = document.getElementsByClassName('box content')[0].clientWidth; 
    //imgH = document.getElementsByClassName('box content')[0].clientHeight; 
    imgW = 1088; 
    imgH = 1088; 
    //alert(vpW + ':' + vpH + ' = ' + vpW/vpH + '      ' + imgW + ':' + imgH + ' = ' + imgW/imgH); 
 
    if(vpW/vpH < imgW/imgH) { 
        for(var i = 0; i < 2; i++) { 
            document.getElementsByClassName('horizontalbar')[i].style.height = (vpH - vpW)/2 + 'px'; 
            document.getElementsByClassName('box sidebar')[i].style.width = '0px'; 
        } 
    } else { 
        for(var i = 0; i < 2; i++) { 
            document.getElementsByClassName('box sidebar')[i].style.width = (vpW - vpH)/2 + 'px'; 
            document.getElementsByClassName('horizontalbar')[i].style.height = '0px' 
        } 
    } 
}

Answer 1

Что должна делать функция:

var f = function(a) { 
  console.log(a) 
}; 
 
// затормозить функцию до одного раза в 1000 мс 
var f1000 = throttle(f, 1000); 
 
f1000(1); // выведет 1 
f1000(2); // (тормозим, не прошло 1000 мс) 
f1000(3); // (тормозим, не прошло 1000 мс) 
 
// когда пройдёт 1000 мс... 
// выведет 3, промежуточное значение 2 игнорируется

Как работает функция:

function throttle(func, ms) { 
 
  var isThrottled = false, 
    savedArgs, 
    savedThis; 
 
  function wrapper() { 
 
    if (isThrottled) { // (2) 
      savedArgs = arguments; 
      savedThis = this; 
      return; 
    } 
 
    func.apply(this, arguments); // (1) 
 
    isThrottled = true; 
 
    setTimeout(function() { 
      isThrottled = false; // (3) 
      if (savedArgs) { 
        wrapper.apply(savedThis, savedArgs); 
        savedArgs = savedThis = null; 
      } 
    }, ms); 
  } 
 
  return wrapper; 
}
Шаги работы этой функции:

  1. Декоратор throttle возвращает функцию-обёртку wrapper, которая при первом вызове запускает func и переходит в состояние «паузы» (isThrottled = true).
  2. В этом состоянии все новые вызовы запоминаются в замыкании через savedArgs/savedThis. Обратим внимание, что и контекст вызова и аргументы для нас одинаково важны и запоминаются одновременно. Только зная и то и другое, можно воспроизвести вызов правильно.
  3. Далее, когда пройдёт таймаут ms миллисекунд – пауза будет снята, а wrapper – запущен с последними аргументами и контекстом (если во время паузы были вызовы).

(Источник)

Answer 2

Если throttle реализована правильно, то должно работать. Попробуйте протестировать со throttle из библиотеки underscore. Пример из документации:

var throttled = _.throttle(updatePosition, 100);
$(window).scroll(throttled);
READ ALSO
Как сделать счетчик javascript?

Как сделать счетчик javascript?

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

178
Подсветка курсора

Подсветка курсора

Доброго времени суток!

171
Картинка перед выбранным текстом в select

Картинка перед выбранным текстом в select

Как можно вставить картинку (календарик) перед выбранным месяцем в select?

177