marcj / css-element-queries

CSS Element-Queries aka Container Queries. High-speed element dimension/media queries in valid css.
http://marcj.github.io/css-element-queries/
MIT License
4.27k stars 487 forks source link

Using ResizeObserver to implement ResizeSensor for the latest modern browsers. #309

Open fengdh opened 3 years ago

fengdh commented 3 years ago

ResizeObserver is available for the latest modern browsers for a while. Instead of inserting tricky DIV to catch "resize" event, it is better to simply use ResizeObserver.

image

For backward compability, I rewrite ResizeSensor with ResizeObserver (and Map) as an AMD module below. It works well for my project.

define(function() {
    const observing = new Map(),
          ro = new ResizeObserver(entries => {
                    for (let {target} of entries) {
                        (observing.get(target) || []).forEach(({callback}) => callback(target));
                    }
                });

    function ResizeSensor(elm, callback) {
        observing.set(elm, [...observing.get(elm) || [], {callback, sensor: this]);
        ro.observe(this.elm = elm);
    }

    ResizeSensor.prototype = {
        constructor: ResizeSensor,
        detach() {
            let elm = this.elm;
            ro.unobserve(elm);
            observing.set(elm, [...observing.get(elm) || []].filter(({sensor}) => sensor !== this));
        }
    }

    return ResizeSensor;
});
Aymkdn commented 3 years ago

Thanks for sharing!

You missed a }, and also I rewrote it to be used with import ResizeSensor from './ResizeSensor.js' in my Webpack project:

const observing = new Map(), ro = new ResizeObserver(entries => {
  for (let { target } of entries) {
    (observing.get(target) || []).forEach(({
      callback
    }) => callback(target));
  }
});

function ResizeSensor(elm, callback) {
  observing.set(elm, [...observing.get(elm) || [], {
    callback,
    sensor: this
  }]); // the missing '}' was there
  ro.observe(this.elm = elm);
}

ResizeSensor.prototype = {
  constructor: ResizeSensor,
  detach() {
    let elm = this.elm;
    ro.unobserve(elm);
    observing.set(elm, [...observing.get(elm) || []].filter(({
      sensor
    }) => sensor !== this));
  }
}

export default ResizeSensor;