Андрей Мотошин Front-end engineer

Буфер для изменения размеров окна

#javascript, #jQuery

Последнее время в работе я стараюсь использовать виджетную организацию javascript. Примерно как вот здесь. Это дает приятную гибкость в разработке.

А если виджетам нужно менять свои размеры в зависимости от размеров окна, я использую буфер, который создает setTimeout на 100 миллисекунд, затем выполняет уже сам процесс пересчета своей ширины. Это нужно потому, что браузерный ресайз срабатывает слишком часто и из-за этого бывают ошибки javascript или сильное замедление перерисовки страницы.

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

function ResizeBuffer(){

  var _this = this;
  this.win = $(window);
  this.win.on('resize.resize-buffer', function(){
    _this.resize();
  });

}

ResizeBuffer.prototype.resize = function(){

  var _this = this;
  if (this.resizeTimer) {
    clearTimeout(this.resizeTimer);
  }
  this.resizeTimer = setTimeout(function(){
    _this.win.trigger('resize-buffer');
  }, 100);

};

Здесь происходит то же самое, что и в вышеописанном буфере, но вместо выполнения кода виджета, запускается событие resize-buffer, на которое и нужно подписываться в виджетах:

$(window).on('resize-buffer', function(){
  // то, что должно происходить при ресайзе
});

UPD: коллега подсказал, как можно упростить и ускорить вышеприведенный буфер:

(function(){

  var delay = 100, start, timer;

  var resize = function(){
    if (new Date() - start < delay) {
      setTimeout(resize, delay);
    } else {
      win.trigger('resize-buffer');
      timer = false;
    }
  };

  var win = $(this).on('resize.buffer', function(){
    start = new Date();
    if (!timer) {
      timer = setTimeout(resize, delay);
    }
  });

})();

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

Подписываться на этот буфер в виджетах нужно так же, как и на прошлый вариант.