vue.js中window.onresize的超詳細(xì)使用方法
前言
最近做的項(xiàng)目老是涉及到大小屏切換,但是因?yàn)槠聊粚捀卟灰粯拥脑颍鲜且?jì)算表格高度
window.onresize:監(jiān)聽(tīng)window窗口變化,當(dāng)窗口大小發(fā)生變化時(shí),會(huì)觸發(fā)此事件
含義
MDN中的定義是這樣子的:
文檔視圖調(diào)整大小時(shí)會(huì)觸發(fā) resize事件。
在js中使用
window.onresize = function(){
// todo event
}
在html中使用
<body onresize="myFunction()">
在vue中的使用
需要注意的是,this在函數(shù)中指的是window,而不是vue實(shí)例
mounted(){
const _this = this
window.onresize = function(){
_this.width = document.body.clientWidth
// todo event
}
}
需要注意的兩點(diǎn):
1、this在函數(shù)中不可用,他在函數(shù)中不一定指全局上下文
解決辦法如下:
const _this = this
window.onresize = function(){
_this.width = document.body.clientWidth
}
2、在谷歌瀏覽器中,window.onresize會(huì)觸發(fā)兩次,網(wǎng)上說(shuō)是谷歌瀏覽器的bug
解決辦法如下,設(shè)定一個(gè)標(biāo)識(shí)
let flag = true
window.onresize = function () {
if (flag) {
console.log(new Date(), '窗口改變了')
flag = false
}
let timeId = setTimeout(() => {
flag = true
timeId = null // 清除延時(shí)定時(shí)器
}, 1000)
}
沒(méi)使用flag之前
![[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-CutMjFRk-1678451210887)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ffb54874-0624-453a-a431-eff7c395a11a/Untitled.png)]](http://img.jbzj.com/file_images/article/202312/2023122310410323.png)
使用之后,如下圖,控制臺(tái)只打印了一遍

注意在項(xiàng)目中的使用
1、window.onresize只能在一個(gè)組件中使用,如果多個(gè)組件調(diào)用則會(huì)出現(xiàn)覆蓋情況,所以我的解決方案是在App.vue中使用,獲取document.documentElement.clientWidth(即瀏覽器寬度)存放在vuex中,別的組件只需要用computed(計(jì)算屬性)將vuex的clientWidth獲取,然后通過(guò)watch監(jiān)聽(tīng)clientWidth的值,即可觸發(fā)組件事件
2、由于window.onresize是全局事件,在其他頁(yè)面改變界面時(shí)也會(huì)執(zhí)行,這樣可能會(huì)出現(xiàn)問(wèn)題,需要在出這個(gè)界面時(shí)注銷(xiāo)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
},
注銷(xiāo)之后,切換到其他頁(yè)面,控制臺(tái)就不會(huì)輸出以下信息

window.addEventListener
mounted() {
this.$nextTick(() => {
this.onDrawLine()
window.addEventListener('resize', this.resize())
})
},
beforeDestroy() {
console.log('刪除了')
// 具名函數(shù)使用removeEventListener清除,但是匿名函數(shù)不行
window.removeEventListener('resize', this.resize())
},性能優(yōu)化
window.onresize 在監(jiān)聽(tīng)窗口變化時(shí),固然起到很好的效果,但是對(duì)于網(wǎng)頁(yè)性能消耗過(guò)大。因?yàn)?code>html中每個(gè)標(biāo)簽的變化,都會(huì)觸發(fā)window.onresize 事件,比如顯示/隱藏某個(gè)抽屜、添加/刪除某個(gè)div等等,很有可能會(huì)造成循環(huán)觸發(fā)和無(wú)限制觸發(fā),于是新推出了另外一個(gè)事件**ResizeObserver(對(duì)element和svgelement元素進(jìn)行監(jiān)聽(tīng))**
MDN定義如下:
ResizeObserver避免了通過(guò)回調(diào)函數(shù)調(diào)整大小時(shí),通常創(chuàng)建的無(wú)限回調(diào)循環(huán)和循環(huán)依賴(lài)項(xiàng)。它只能通過(guò)在后續(xù)的幀中處理 DOM 中更深層次的元素來(lái)做到這一點(diǎn)。如果它的實(shí)現(xiàn)遵循規(guī)范,則應(yīng)在繪制前和布局后調(diào)用 resize 事件。
MDN示例:https://mdn.github.io/dom-examples/resize-observer/resize-observer-text.html
部分源碼如下:
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);
}
});
副作用:兼容性不強(qiáng),有些瀏覽器兼容,具體情況見(jiàn)Can I Use
參考鏈接:
- https://www.cnblogs.com/yxysuanfa/p/6878016.html
- http://www.dbjr.com.cn/article/245030.htm
- https://developer.mozilla.org/zh-CN/docs/Web/API/ResizeObserver
總結(jié)
到此這篇關(guān)于vue.js中window.onresize的超詳細(xì)使用方法的文章就介紹到這了,更多相關(guān)window.onresize使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue項(xiàng)目百度地圖如何自定義標(biāo)注marker
這篇文章主要介紹了vue項(xiàng)目百度地圖如何自定義標(biāo)注marker問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
詳解vue項(xiàng)目打包后通過(guò)百度的BAE發(fā)布到網(wǎng)上的流程
這篇文章主要介紹了將vue的項(xiàng)目打包后通過(guò)百度的BAE發(fā)布到網(wǎng)上的流程,主要運(yùn)用的技術(shù)是vue+express+git+百度的應(yīng)用引擎BAE。需要的朋友可以參考下2018-03-03
vueCli?4.x升級(jí)5.x報(bào)錯(cuò):Progress?Plugin?Invalid?Options的解決方法
本文主要介紹了vueCli?4.x升級(jí)5.x報(bào)錯(cuò):Progress?Plugin?Invalid?Options的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-01-01
淺談Vue.nextTick 的實(shí)現(xiàn)方法
本篇文章主要介紹了Vue.nextTick 的實(shí)現(xiàn)方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10
Vue3實(shí)現(xiàn)動(dòng)態(tài)高度的虛擬滾動(dòng)列表的示例代碼
虛擬滾動(dòng)列表是一種優(yōu)化長(zhǎng)列表渲染性能的技術(shù),通過(guò)只渲染可視區(qū)域內(nèi)的列表項(xiàng),減少DOM的渲染數(shù)量,本文就來(lái)介紹一下Vue3實(shí)現(xiàn)動(dòng)態(tài)高度的虛擬滾動(dòng)列表的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下2025-01-01
Vue.set()和this.$set()使用和區(qū)別
我們發(fā)現(xiàn)Vue.set()和this.$set()這兩個(gè)api的實(shí)現(xiàn)原理基本一模一樣,那么Vue.set()和this.$set()的區(qū)別是什么,本文詳細(xì)的介紹一下,感興趣的可以了解一下2021-06-06
vue-cli項(xiàng)目代理proxyTable配置exclude的方法
今天小編就為大家分享一篇vue-cli項(xiàng)目代理proxyTable配置exclude的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
vue 使用print-js 打印渲染不出來(lái)問(wèn)題
這篇文章主要介紹了vue 使用print-js 打印渲染不出來(lái)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10

