前端监测窗口尺寸和元素尺寸变化的方法
前端监测窗口尺寸变化和元素尺寸变化的方法
window.resize
简介
window.resize事件是浏览器提供的一种事件,用于监听窗口大小的改变。这意味着当用户调整浏览器窗口大小时,相关的JavaScript代码将被触发执行。这为开发者提供了一种机制,可以在不同屏幕尺寸下优化网页布局和样式。
注意事项
- 性能问题:
resize事件可能会频繁触发,尤其是在用户拖动窗口大小时。如果事件处理函数中有复杂的逻辑,可能会导致性能问题。可以使用防抖(debounce)技术来减少事件触发的频率。 - 防抖处理:防抖是一种性能优化技术,它可以确保事件处理函数在一定时间内只执行一次,即使事件被多次触发。
语法结构
window.addEventListener('resize', function() {console.log('窗口大小发生了变化');// 在这里添加你的逻辑
});
示例
假设你有一个 div 元素,你希望在窗口大小变化时调整它的宽度和高度
<div id="resizableDiv" style="width: 50%; height: 50%; background-color: lightblue;"></div>
window.addEventListener('resize', function() {var div = document.getElementById('resizableDiv');div.style.width = window.innerWidth * 0.5 + 'px';div.style.height = window.innerHeight * 0.5 + 'px';
});
防抖处理
function debounce(func, wait) {var timeout;return function() {clearTimeout(timeout);timeout = setTimeout(func, wait);};
}window.addEventListener('resize', debounce(function() {console.log('窗口大小发生了变化(防抖处理)');// 在这里添加你的逻辑
}, 250));
resizeObserver
ResizeObserver 是一个现代的浏览器 API,用于监听 DOM 元素的大小变化。
与传统的 window.resize 事件不同,ResizeObserver 可以精确地监听某个特定元素的大小变化,而不仅仅是窗口大小的变化。
可以实时获取元素的尺寸变化,并进行相应的操作。
用法
1、创建 resizeObserver 实例
需要一个 回调函数 作为参数,这个回调函数会在监测元素的大小发生变化时被触发。
const observer = new ResizeObserver(callback);
2、指定监测的目标元素
它可以是任何DOM元素,例如一个<div>元素或其他HTML元素
const target = document.querySelector('#elementToObserve');
observer.observe(target);
3、编写回调函数
回调函数会在元素的大小或位置变化时被触发,它接受两个参数:entries 和 observer。
-
entries:一个Resize Observer Entry对象的数组,每个对象描述了一个被观察元素的尺寸和位置变化。
-
observer:对观察器本身的引用。通常用于在回调函数中进行操作,例如停止观察或处理被观察元素的变化
entries 的contentRect 属性中包含了被观察元素的信息,包括宽度(width)和高度(height)
const callback = (entries, observer) => {entries.forEach(entry => {const { target, contentRect } = entry;// 处理元素尺寸变化// contentRect包含了元素的新尺寸和位置信息const target = entry.target; const contentRect = entry.contentRect;console.log(`目标元素: ${target}`); console.log(`宽度: ${contentRect.width}px`);console.log(`高度: ${contentRect.height}px`);});
};
示例
vue3项目实现echarts图表大小自适应 .vue文件拆分
<template><div ref="chartContainer" :style="{ width: containerWidth, height: containerHeight }"><div style="width: 100%; height: 100%" ref="chartLineDom"></div></div>
</template>
<script lang="ts" setup>
import { ref, onMounted, watch, onBeforeUnmount} from 'vue'
import * as echarts from 'echarts'//接收父组件传值
const props = defineProps({xdata: {type: Array,default: () => []},y1: {type: Array,default: () => []},y2: {type: Array,default: () => []},title: {type: String,default: () => ''},legend: {type: Array,default: () => []}
})// 父元素
const containerWidth = ref('100%')
const containerHeight = ref('500px')
const chartContainer = ref<any>(null)
// resizeObserver 实例
const resizeObserver = ref<any>(null)// 声明echarts实例
const chartLineDom = ref()
// 图表实例
let myChart = ref<any>(null)// 监听窗口变化,调整图表大小
const resizeChart = () => {if (myChart.value) {myChart.value.resize()}
}onMounted(() => {showChart()if (chartContainer.value) {resizeObserver.value = new ResizeObserver(resizeChart)resizeObserver.value.observe(chartContainer.value)}
})onBeforeUnmount(() => {if (myChart.value) {myChart.value.dispose()myChart.value = null}if (resizeObserver.value) {resizeObserver.value.disconnect()resizeObserver.value = null}
})watch(() => props.xdata,() => {showChart()},{deep: true}
)const showChart = () => {if (!myChart.value) {myChart.value = echarts.init(chartLineDom.value)}// 按对应格式装载数据并赋予下方const option = {xAxis: {type: 'category',data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']},yAxis: {type: 'value'},series: [{data: [120, 200, 150, 80, 70, 110, 130],type: 'bar'}]}myChart.value.setOption(option)
}// 导出图片 -- base64格式;父组件拿到值后直接展示在img的src属性中即可
const getChartImg = () => {return myChart.value.getDataURL({type: 'png',pixelRatio: 2,backgroundColor: '#fff'})
}// 暴露给父组件 -- 以供父组件生成图片
defineExpose({ getChartImg })
</script>
<style scoped>
div {transition:width 0.3s,height 0.3s;
}
</style>
存在一个问题(js部分):使用
const myChart = ref<any>(null)对echarts 图表 进行实例声明时,其不再具备大小自适应;而使用const resizeObserver = ref<any>(null)对resizeObserver进行实例声明则无影响。
原因分析
- ref: Vue 3 提供的响应式 API,用于创建一个响应式变量;通常用于在 Vue 组件的 < script setup > 中声明响应式变量。变量是响应式的,当它的值发生变化时,Vue 会自动更新依赖它的视图。
- let :普通 JavaScript 变量,非响应式。用于声明一个普通的变量,不需要响应式特性。变量是非响应式的,修改它的值不会触发 Vue 的更新机制。
本示例中的 myChart 声明的是一个echarts实例,通常不需要vue的响应式特性,因为它的更新和操作都是通过 ECharts 的 API 完成的,而不是通过 Vue 的响应式系统。因此,使用 let myChart = null 是更合适的选择。
resizeObserver.value.observe(chartContainer.value) 的行为同样也不依赖 Vue 的响应式系统。它的工作原理是基于浏览器的原生 ResizeObserver API,与 Vue 的响应式机制无关。所以使用let进行声明其不会影响其功能。
回到初始问题,使用ref声明echarts实例后,在使用Echarts自带的resize() API进行自适应时报错,其无法自适应大小。
控制台报错信息如下:

无法读取未定义的属性(读取“type”)
ref 创建的对象默认是响应式的。这意味着当你改变 myChart 的内容时,Vue 会自动追踪这个对象并触发视图的更新。然而,Echarts 实例本身是一个复杂的对象,它并不需要或不适应 Vue 的响应式系统,因为 Vue 无法有效地追踪和更新 echarts 实例的状态。
myChart 会被 Vue 的响应式系统通过 Proxy 代理,从而让它变成响应式对象。由于 Proxy 是 Vue 3 实现响应式的核心方式,当你访问 myChart 时,它被转换为代理对象,并且 Proxy 会拦截访问行为。这可能导致一些性能问题或行为异常,尤其是在你手动操作 echarts 实例时,比如调用 resize 方法,或者访问像 coordSys.type 这样的属性。
在 echarts 中,coordSys 是图表实例的坐标系对象,通常是直接访问其内部属性,如 coordSys.type,来判断图表的坐标系类型。当 myChart 变成响应式对象时,它的 coordSys 或其他深层属性可能会被 Vue 的代理拦截,从而导致你无法直接访问它,或者它的某些方法不能正常工作。
解决办法:使用markRaw
markRaw 用于标记一个对象,使其在 Vue 的响应式系统中保持“原始状态”。这意味着被 markRaw 标记的对象在 Vue 的响应式逻辑中不会被代理,因此不会变为响应式对象。
即,标记一个对象,使其永远不会变成响应式的。
// 接上一个javascript代码块 这里是代码片段
import { markRaw } from 'vue'const showChart = () => {if (!myChart.value) {myChart.value = markRaw(echarts.init(chartLineDom.value))}
}
与markRaw相对应的 toRaw
作用:用于获取一个响应式对象的原始对象,toRaw 返回的对象不再是响应式的,不会触发视图更新。
使用场景:在需要将响应式对象传递给非 Vue 的库或外部系统时,使用 toRaw 可以确保它们收到的是普通对象。
<script setup lang='ts' >
import { reactive, toRaw } from 'vue';// person 是响应式数据
const person = reactive({name: 'Tom',age:20,
})
// rawPerson 原始数据
const rawPerson = toRaw(person)// 对比
console.log('响应式数据',person);
console.log('原始数据',rawPerson);
// 响应式数据 可修改
const changeAge = () => {person.age += 1;
}
// 原始数据 不可修改
const rawChangeAge = () => {console.log('rawPerson中的age',rawPerson.age);rawPerson.age += 1;
}
</script>
相关文章:
前端监测窗口尺寸和元素尺寸变化的方法
前端监测窗口尺寸变化和元素尺寸变化的方法 window.resize 简介 window.resize事件是浏览器提供的一种事件,用于监听窗口大小的改变。这意味着当用户调整浏览器窗口大小时,相关的JavaScript代码将被触发执行。这为开发者提供了一种机制,可…...
angular中下载接口返回文件
目录 一、URL.createObjectURL() 一、URL.createObjectURL() createObjectURL属于js的原生方法,位于window.URL上,用于将Blob或者File文件转换为可以临时的URL地址进行显示 **注意**:Angular 的 HttpClient 默认将响应解析为 JSON 对象16。…...
ubuntu 部署deepseek
更新 apt update 升级 apt upgrade 格式化硬盘 mkfs.ext4 /dev/sdb 安装nginx 查看端口 一、安装Ollama Ollama是一个开源的大型语言模型(LLM)推理服务器,为用户提供了灵活、安全和高性能的语言模型推理解决方案。 ollama/docs/linux.m…...
【每日学点HarmonyOS Next知识】拖拽调整列表顺序、tab回弹、自定义弹窗this、状态变量修饰枚举
1、HarmonyOS 功能实现(拖拽调整列表顺序)? 可参考: import curves from ohos.curves; import Curves from ohos.curvesEntry Component struct ListItemExample {State private arr: number[] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]…...
MySQL库和表的操作详解:从创建库到表的管理全面指南
目录 一、MySQL库的操作详解 〇、登录MySQL 一、数据库的创建与字符集设置 1. 创建数据库的语法 2. 创建数据库示例 查看创建出来的文件: bash下查看MySQL创建的文件 二、字符集与校验规则 1. 查看系统默认设置 2. 查看支持的字符集与校验规则 3. 校验规则对查询的影响…...
PyTorch 系列教程:使用CNN实现图像分类
图像分类是计算机视觉领域的一项基本任务,也是深度学习技术的一个常见应用。近年来,卷积神经网络(cnn)和PyTorch库的结合由于其易用性和鲁棒性已经成为执行图像分类的流行选择。 理解卷积神经网络(cnn) 卷…...
Docker下ARM64架构的源码编译Qt5.15.1,并移植到开发板上
Docker下ARM64架构的源码编译Qt5.15.1,并移植到开发板上 1、环境介绍 QT版本:5.15.1 待移植环境: jetson nano 系列开发板 aarch64架构(arm64) 编译环境: 虚拟机Ubuntu18.04(x86_64) 2、…...
Java 大视界 -- Java 大数据中的数据可视化大屏设计与开发实战(127)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
starrocks批量启停脚本
#!/bin/bash # 定义 StarRocks 安装目录 STARROCKS_HOME"/path/to/starrocks" # 定义 FE 和 BE 节点列表 FE_NODES("fe_node1_ip" "fe_node2_ip" "fe_node3_ip") BE_NODES("be_node1_ip" "be_node2_ip" "be_…...
「Unity3D」UGUI将元素固定在,距离屏幕边缘的某个比例,以及保持元素自身比例
在不同分辨率的屏幕下,UI元素按照自身像素大小,会发生位置与比例的变化,本文仅利用锚点(Anchors)使用,来实现UI元素,固定在某个比例距离的屏幕边缘。 首先,将元素的锚点设置为中心&…...
4.3 数组和集合的初始及赋值
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的 版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商…...
Deep research深度研究:ChatGPT/ Gemini/ Perplexity/ Grok哪家最强?(实测对比分析)
目前推出深度研究和深度检索的AI大模型有四家: OpenAI和Gemini 的deep research,以及Perplexity 和Grok的deep search,都能生成带参考文献引用的主题报告。 致力于“几分钟之内生成一份完整的主题调研报告,解决人力几小时甚至几天…...
关于sqlalchemy的ORM的使用
关于sqlalchemy的ORM的使用 二、创建表三、使用数据表、查询记录三、批量插入数据四、关于with...as...:的使用 二、创建表 使用Mapped来映射字段 from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker,Mapped,mapped_columnBa…...
【leetcode hot 100 148】排序序列
解法一:(双重循环)第一个循环head,逐步将head的node加入有序列表;第二个循环在有序列表中找到合适的位置,插入node。 /*** Definition for singly-linked list.* public class ListNode {* int val;* …...
3-001:MySQL 中的回表是什么?
1. 什么是回表? 回表(Back to Table) 指的是 在使用非聚簇索引(辅助索引)查询时,MySQL 需要 先通过索引找到主键 ID,然后再回到主键索引(聚簇索引)查询完整数据…...
单片机设计暖脚器研究
标题:单片机设计暖脚器研究 内容:1.摘要 本文聚焦于基于单片机设计暖脚器的研究。背景方面,在寒冷季节,暖脚器能有效改善脚部寒冷状况,提升人们的舒适度,但传统暖脚器存在功能单一、温控不准确等问题。目的是设计一款智能、高效且…...
【Linux】在VMWare中安装Ubuntu操作系统(2025最新_Ubuntu 24.04.2)#VMware安装Ubuntu实战分享#
今天田辛老师为大家带来一篇关于在VMWare虚拟机上安装Ubuntu系统的详细教程。无论是学习、开发还是测试,虚拟机都是一个非常实用的工具,它允许我们在同一台物理机上运行多个操作系统。Ubuntu作为一款开源、免费且用户友好的Linux发行版,深受广…...
AutoGen学习笔记系列(十三)Advanced - Logging
这篇文章瞄的是AutoGen官方教学文档 Advanced 章节中的 Logging 篇章,介绍了怎样在使用过程中添加日志信息,其实就是使用了python自带的日志库 logging。 官网链接:https://microsoft.github.io/autogen/stable/user-guide/agentchat-user-g…...
scrcpy pc机远程 无线 控制android app 查看调试log
背景: 公司的安卓机,是那种大屏幕的连接usb外设的。不好挪动,占地方,不能直接连接pc机上的android stduio来调试。 所以从网上找了一个python adb.exe控制器,可以局域网内远程控制开发的app,并在android stduio上看…...
UE5.5 Niagara发射器更新属性
发射器属性 在 Niagara 里,Emitter 负责控制粒子生成的规则和行为。不同的 Emitter 属性决定了如何发射粒子、粒子如何模拟、计算方式等。 发射器 本地空间(Local Space) 控制粒子是否跟随发射器(Emitter)移动。 ✅…...
深度剖析Redis:双写一致性问题及解决方案全景解析
在高并发场景下,缓存与数据库的双写一致性是每个开发者必须直面的核心挑战。本文通过5大解决方案,带你彻底攻克这一技术难关! 一、问题全景图:当缓存遇到数据库 1.1 典型问题场景 // 典型问题代码示例 public void updateProduc…...
MongoDB备份与还原
备份恢复工具介绍 1)mongoexport/mongoimport 2)mongodump/mongorestore 备份工具区别 mongoexport/mongoimport 导入/导出的是JSON格式或者CSV格式 mongodump/mongorestore 导入/导出的是BSON格式。二进制方式,速度快 1)…...
计算机:基于深度学习的Web应用安全漏洞检测与扫描
目录 前言 课题背景和意义 实现技术思路 一、算法理论基础 1.1 网络爬虫 1.2 漏洞检测 二、 数据集 三、实验及结果分析 3.1 实验环境搭建 3.2 模型训练 最后 前言 📅大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,…...
postgresql14编译安装脚本
#!/bin/bash####################################readme################################### #先上传postgresql源码包,再配置yum源,然后执行脚本 #备份官方yum源配置文件: #cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS…...
Java 大视界 -- Java 大数据在智能安防视频摘要与检索技术中的应用(128)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
部署项目至服务器:响应时间太长,无法访问此页面?
在我们部署项目到服务器上的时候,一顿操作猛如虎,打开页面..... 这里记录一下这种情况是怎么回事。一般就是服务器上的安全组没有放行端口。 因为我是用宝塔进行项目部署的。所以遇到这种情况,要去操作两边(宝塔and服务器所属平台…...
如何搭建一个适配微信小程序,h5,app的uni-app项目
在vscode搭建 uni-app 项目(Vue 3 Vite Pinia uView Plus) 一、环境准备 1. 安装 Node.js 确保已安装 Node.js(需≥14版本),可通过以下命令检查版本: node -v2. 安装 VSCode 从 VSCode 官网 下载并…...
【数据结构】List介绍
目录 1. 什么是List 2. 常见接口介绍 3. List的使用 1. 什么是List 在集合框架中,List是一个接口,继承自Collection。此时extends意为拓展 Collection也是一个接口,该接口中规范了后序容器中常用的一些方法,具体如下所示&…...
vs2022用git插件重置--删除更改(--hard)后恢复删除的内容
1、先到项目工程中打开需要恢复的分支。 2、进入代码管理根目录文件夹。 3、在根目录文件夹点右键,点git bash here 正常情况下如果git目录权限足够,是可以如上图所示显示当前分支和当前目录的。 在git权限不足的情况下会出现如下提示: …...
【C++】【数据结构】链表与线性表
线性表和链表优缺点及适用场景 线性表(以数组为例) 优点:随机访问效率高,可通过下标直接访问元素,时间复杂度为 O (1);存储密度大,内存连续存储,空间利用率高。缺点:插入…...
