首页IT科技window.onresize 无效(window.onresize的详细使用)

window.onresize 无效(window.onresize的详细使用)

时间2025-08-05 03:39:48分类IT科技浏览6261
导读:最近做的项目老是涉及到大小屏切换,但是因为屏幕宽高不一样的原因,老是要计算表格高度...

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

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

含义

MDN中的定义是这样子的:

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

在js中使用

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

在html中使用

<body onresize="myFunction()">

在vue中的使用

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

mounted(){ const _this = this window.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 = true window.onresize = function () { if (flag) { console.log(new Date(), 窗口改变了) flag = false } let timeId = setTimeout(() => { flag = true timeId = null // 清除延时定时器 }, 1000) }

没使用flag之前

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

注意在项目中的使用

1       、window.onresize只能在一个组件中使用,如果多个组件调用则会出现覆盖情况                    ,所以我的解决方案是在App.vue中使用                    ,获取document.documentElement.clientWidth(即浏览器宽度)存放在vuex中    ,别的组件只需要用computed(计算属性)将vuex的clientWidth获取                ,然后通过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 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); } });

副作用:兼容性不强                ,有些浏览器兼容                    ,具体情况见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

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
bearer token原理(前端如何给bearer token传值) cka模拟试题(CKA考试题目常用命令-练习这个就完事)