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 window
window 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. this
It 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.onresize
it 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
After use, as shown in the figure below, the console only prints once
Note the use in the project
1. window.onresize
It 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 vuex
get clientWidth
it, and then monitor the value of clientWidth through watch to trigger component events
2. Since window.onresize
it 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
window.addEventListener
mounted() {
this.$nextTick(() => {
this.onDrawLine()
window.addEventListener('resize', this.resize())
})
},
beforeDestroy() {
console.log('删除了')
// 具名函数使用removeEventListener清除,但是匿名函数不行
window.removeEventListener('resize', this.resize())
},
performance optimization
window.onresize
When monitoring window changes, it has a good effect, but it consumes too much web page performance. Because html
each label change in will trigger window.onresize
an 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:
ResizeObserver
Avoids 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