window.onresize的详细使用
创始人
2024-06-01 07:53:33
0

最近做的项目老是涉及到大小屏切换,但是因为屏幕宽高不一样的原因,老是要计算表格高度

window.onresize:监听window窗口变化,当窗口大小发生变化时,会触发此事件

含义

MDN中的定义是这样子的:

文档视图调整大小时会触发 resize事件。

在js中使用

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

在html中使用


在vue中的使用

需要注意的是,this在函数中指的是window,而不是vue实例

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

需要注意的两点:

1、this在函数中不可用,他在函数中不一定指全局上下文

解决办法如下:

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

2、在谷歌浏览器中,window.onresize会触发两次,网上说是谷歌浏览器的bug

解决办法如下,设定一个标识

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

没使用flag之前

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CutMjFRk-1678451210887)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ffb54874-0624-453a-a431-eff7c395a11a/Untitled.png)]

使用之后,如下图,控制台只打印了一遍

在这里插入图片描述

注意在项目中的使用

1、window.onresize只能在一个组件中使用,如果多个组件调用则会出现覆盖情况,所以我的解决方案是在App.vue中使用,获取document.documentElement.clientWidth(即浏览器宽度)存放在vuex中,别的组件只需要用computed(计算属性)将vuexclientWidth获取,然后通过watch监听clientWidth的值,即可触发组件事件

2、由于window.onresize是全局事件,在其他页面改变界面时也会执行,这样可能会出现问题,需要在出这个界面时注销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
},

注销之后,切换到其他页面,控制台就不会输出以下信息

在这里插入图片描述

window.addEventListener


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

性能优化

window.onresize 在监听窗口变化时,固然起到很好的效果,但是对于网页性能消耗过大。因为html中每个标签的变化,都会触发window.onresize 事件,比如显示/隐藏某个抽屉、添加/删除某个div等等,很有可能会造成循环触发和无限制触发,于是新推出了另外一个事件**ResizeObserver(对element和svgelement元素进行监听)**

MDN定义如下:

ResizeObserver避免了通过回调函数调整大小时,通常创建的无限回调循环和循环依赖项。它只能通过在后续的帧中处理 DOM 中更深层次的元素来做到这一点。如果它的实现遵循规范,则应在绘制前和布局后调用 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 arrayconst 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);}
});

副作用:兼容性不强,有些浏览器兼容,具体情况见Can I Use

参考链接:

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

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...