首页 > 解决方案 > addListener 幕后

问题描述

在过去,我还使用了一个requestAnimationFrame与它捆绑在一起的调整大小侦听器,作为轮询调整大小事件的某种优化版本:

/**
 * Resize listener
 * @return {function}
 */
export const optimizedResize = (function () {
  let callbacks = [],
    running = false;

  // fired on resize event
  function resize() {
    if (!running) {
      running = true;

      if (window.requestAnimationFrame) {
        window.requestAnimationFrame(runCallbacks);
      } else {
        setTimeout(runCallbacks, 66);
      }
    }
  }

  // run the actual callbacks
  function runCallbacks() {
    callbacks.forEach((callback) => {
      callback();
    });

    running = false;
  }

  // adds callback to loop
  function addCallback(callback) {
    if (callback) {
      callbacks.push(callback);
    }
  }

  return {
    // public method to add additional callback
    add(callback) {
      if (!callbacks.length) {
        window.addEventListener('resize', resize);
      }
      addCallback(callback);
    },
  };
}());

我最近遇到了addListener()令人尴尬的事情,我必须说我不熟悉。尽管它说它只是addEventListener()语法的别名,但听更改似乎很简单:

const viewportMediumMin = window.matchMedia(`(min-width: 768px)`);

viewportMediumMin.addListener(checkScreenSize);

但是,我想弄清楚的addListener()是相当于:

window.addEventListener('resize', function() {
    console.log('addEventListener - resize');
}, true);

或者如果它在幕后做一些“更聪明”的事情,我应该完全依赖它,与optimizedResize我提到的方法相比。我真的只对媒体查询更改的特定事件感兴趣,而不是找出每一个像素宽度的变化。谢谢你的帮助!

标签: javascript

解决方案


This is basically reinventing wheels. CSS3 was made to style the pages content gracefully on different screen sizes, and media queries were added to change the look of a page at a certain breakpoint. Those breakpoints are common in todays web development, and modern CSS engines were heavily optimized to perform changes as fast as possible. Therefore

 window.matchMedia(`(min-width: 768px)`).addListener(/*...*/)

is probably very performant as the event is detected by the CSS engine that then gets redirected to the JS engine. Adding a listener to resize is probably slower as every pixel change causes a JS event, and your unoptimized JavaScript has to figure out wether a breakpoint was passed. Your optimizeResize doesn't really change that.


推荐阅读