Detailed use of window.onresize

The recent projects always involve switching between large and small screens, but because of the different width and height of the screen, it is always necessary to calculate the height of the table

window.onresize: Monitor windowwindow changes, when the window size changes, this event will be triggered

meaning

The definition in MDN is like this:

The resize event is fired when the document view is resized .

use in js

window.onresize = function(){
	// todo event
}

use in html

<body onresize="myFunction()">

Use in vue

It should be noted that this refers to window in the function, not the vue instance

mounted(){
	const _this = this
	window.onresize = function(){
		_this.width = document.body.clientWidth
		// todo event
	}
}

Two points to note:

1. thisIt is not available in the function, it does not necessarily refer to the global context in the function

The solution is as follows:

const  _this = this
window.onresize = function(){
	_this.width = document.body.clientWidth
}

2. In Google Chrome, window.onresizeit will be triggered twice. It is said on the Internet that it is a bug of Google Chrome

The solution is as follows, set a logo

	let flag = true
    window.onresize = function () {
      if (flag) {
        console.log(new Date(), '窗口改变了')
        flag = false
      }
      let timeId = setTimeout(() => {
        flag = true
        timeId = null // 清除延时定时器
      }, 1000)
    }

Before using the flag

[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-CutMjFRk-1678451210887)(https://s3-us-west-2.amazonaws.com/secure.notion - static.com/ffb54874-0624-453a-a431-eff7c395a11a/Untitled.png)]

After use, as shown in the figure below, the console only prints once

insert image description here

Note the use in the project

1. window.onresizeIt can only be used in one component. If multiple components are called, it will be overwritten, so my solution is to use it in App.vue. The acquisition document.documentElement.clientWidth(ie browser width) is stored in vuex, and other components only You need to use computed(calculated property) to vuexget clientWidthit, and then monitor the value of clientWidth through watch to trigger component events

2. Since window.onresizeit is a global event, it will also be executed when the interface is changed on other pages, which may cause problems, and the event needs to be logged out when the interface is exited window.onresize.

created() {
    this.$bus.$on('resize', this.$_setTableHeight)
    window.onresize = function () {
      console.log(new Date(), '窗口改变了')
    }
},
beforeDestroy() {
    this.$bus.$off('resize', this.$_setTableHeight)
    window.onresize = null
},

After logging out and switching to other pages, the console will not output the following information

insert image description here

window.addEventListener


mounted() {
    this.$nextTick(() => {
      this.onDrawLine()
      window.addEventListener('resize', this.resize())
    })
  },
 beforeDestroy() {
    console.log('删除了')
		// 具名函数使用removeEventListener清除,但是匿名函数不行
    window.removeEventListener('resize', this.resize())
 },

performance optimization

window.onresizeWhen monitoring window changes, it has a good effect, but it consumes too much web page performance. Because htmleach label change in will trigger window.onresizean event, such as showing/hiding a certain drawer, adding/deleting a certain div, etc., which is likely to cause cyclic triggering and unlimited triggering, so another event is newly launched** ResizeObserver (monitoring element and svgelement elements)**

MDN is defined as follows:

ResizeObserverAvoids the infinite callback loop and circular dependencies that are usually created when resizing via a callback function. It can only do this by processing elements deeper in the DOM in subsequent frames. If its implementation follows the spec, the resize event should be called before paint and after layout.

MDN example: https://mdn.github.io/dom-examples/resize-observer/resize-observer-text.html

Part of the source code is as follows:

const h1Elem = document.querySelector('h1');
const pElem = document.querySelector('p');
const divElem = document.querySelector('body > div');
const slider = document.querySelector('input[type="range"]');
const checkbox = document.querySelector('input[type="checkbox"]');

divElem.style.width = '600px';

slider.addEventListener('input', () => {
  divElem.style.width = `${slider.value}px`;
})

const resizeObserver = new ResizeObserver((entries) => {
  for (const entry of entries) {
    if (entry.contentBoxSize) {
      // Firefox implements `contentBoxSize` as a single content rect, rather than an array
      const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;

      h1Elem.style.fontSize = `${Math.max(1.5, contentBoxSize.inlineSize / 200)}rem`;
      pElem.style.fontSize = `${Math.max(1, contentBoxSize.inlineSize / 600)}rem`;
    } else {
      h1Elem.style.fontSize = `${Math.max(1.5, entry.contentRect.width / 200)}rem`;
      pElem.style.fontSize = `${Math.max(1, entry.contentRect.width / 600)}rem`;
    }
  }

  console.log('Size changed');
});

resizeObserver.observe(divElem);

checkbox.addEventListener('change', () => {
  if (checkbox.checked) {
    resizeObserver.observe(divElem);
  } else {
    resizeObserver.unobserve(divElem);
  }
});

Side effects: compatibility is not strong, some browsers are compatible, see Can I Use for details

Reference link:

https://www.cnblogs.com/yxysuanfa/p/6878016.html

https://www.jb51.net/article/245030.htm

https://developer.mozilla.org/zh-CN/docs/Web/API/ResizeObserver

Guess you like

Origin blog.csdn.net/weixin_41886421/article/details/129452097