Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

The first reaction is:

window.addEventListener("resize", handler, useCapture)
Copy the code

Simple, but obvious: Resize events are triggered when document views are resized, only for Windows, whereas normal DOM elements do not have onResize events.

So, to listen for normal DOM element size changes, discard the first sense of error, can choose the following method:

ResizeObserver

ResizeObserver belongs to the Web API

You can listen for changes in an Element’s content area or SVGElement’s bounding box — MDN ResizeObserver

Create and return a ResizeObserver object using the constructor function, New ResizeObserver(callback), and then:

To observe

ResizeObserver.observe(target, options)
Copy the code
  • Start looking at the specified DOM

  • Support for setting which box model the observer will view in: specify the box property of the options parameter. The options include content-box (default), border-box, and device-pixel-content-box. portal

End of observation

ResizeObserver.disconnect()
Copy the code
  • Cancels and ends all target DOM observations
ResizeObserver.unobserve(target)
Copy the code
  • Cancels and ends the observation of the specified DOM

The sample

<script>
export default {
  methods: {
    handleResize() {
      console.log("handle resize"); }},mounted() {
    const dom = this.$refs.target.$el;   // Assume that this.$refs.target returns a VueComponent object
    this.observer = new ResizeObserver(this.handleResize);
    this.observer.observe(dom, { box: "border-box" });
  },
  beforeDestroy() {
    this.observer.disconnect(); }};</script>
Copy the code

When is the callback triggered?

  1. Initialization is performed once
  2. Document window resize will be performed
  3. Element discovery size changes (not caused by 2) are performed

resize-observer-polyfill

ResizeObserver has some browser compatibility problems, see Can I Use for details

The positioning of the NPM package is:

A polyfill for the Resize Observer API.

Implementation based on MutationObserve or Mutation Events: To address browser compatibility issues with the ResizeObserver API

(Please note: There are style issues in IE10 and earlier)

The sample

Element UI merry-go-round and hidden component: scroll bar

// https://github.com/ElemeFE/element/blob/dev/src/utils/resize-event.js
import ResizeObserver from 'resize-observer-polyfill';
import { debounce } from 'throttle-debounce';

export const addResizeListener = function(element, fn) {
  if (isServer) return;
  if(! element.__resizeListeners__) { element.__resizeListeners__ = []; element.__ro__ =new ResizeObserver(debounce(16, resizeHandler));
    element.__ro__.observe(element);
  }
  element.__resizeListeners__.push(fn);
};

// https://github.com/ElemeFE/element/blob/dev/packages/scrollbar/src/main.js
import { addResizeListener, removeResizeListener } from "@/utils/resize-event";

mounted(){!this.noresize && addResizeListener(this.$refs.resize, this.update);
}
Copy the code

element-resize-detector

Resize-observer-polyfill is also an NPM package that monitors changes in the size of DOM elements

Positioning is:

Optimized cross-browser resize listener for elements.

Performance is improved and usage is similar to the ResizeObserver API

To start listening to

ListenTo (Element, listener) or listenTo(Options, Element, listener)Copy the code

The end of the listening

RemoveListener (Element, listener) or removeAllListeners(Element) or uninstall(element)Copy the code

The sample

<script>
import elementResizeDetectorMaker from "element-resize-detector";
export default {
  methods: {
    handleResize() {
      console.log("do resize"); }},mounted() {
    // Must be a DOM element or a collection of DOM elements.
    const dom = this.$refs.col.$el;

    this.observer = elementResizeDetectorMaker();
    this.observer.listenTo(
      { strategy: "scroll" }, // Improve performance based on scrolling
      dom,
      this.handleResize
    );
  },
  beforeDestroy() {
    const dom = this.$refs.col.$el;
    this.observer.removeListener(dom, this.handleResize); }}; </script>Copy the code

vue-resize-observer

Each of the three methods described above requires more or less memorizing some grammar

Q: Why can’t Vue be a custom directive?

A: The main character usually appears at the end. Use vue-resize-Observer

Note: Vue 3.x is supported

The sample

Install, referenced in the entry file:

import VueResizeObserver from "vue-resize-observer";
Vue.use(VueResizeObserver);
Copy the code
<div class="demo" v-resize="handleResize"></div>
Copy the code
export default {
  methods: {
    handleResize(info) {
      console.log("do resize", info); // info output: object, element current width, height}}}; </script>Copy the code

When is handleResize triggered to execute?

  1. Initialization is not performed once
  2. Document window resize will be performed
  3. Element discovery size changes (not caused by 2) are performed

Link portal

How to elegantly monitor container height changes

Last but not least

If there is anything wrong, please give me your advice