You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

导入的尺寸变量在窗口Resize事件中无法更新的问题咨询

问题原因分析

你遇到的核心问题是导出的是函数执行后的静态对象,而非动态更新的引用:

当你写export default sizes();时,实际上是调用了sizes()函数一次,把它返回的对象导出。当业务代码导入size时,拿到的就是这个初始计算的固定对象——哪怕后续resize事件触发了sizes()函数重新计算,新生成的对象和你导入的size没有任何关联,所以打印的值永远不会更新。

另外还有个小问题:你在sizes()函数内部添加了window.addEventListener('resize', sizes),这会导致每次调用sizes()都会新增一个resize监听,重复调用的话会触发多次计算,造成性能浪费。


解决方案

下面提供两种常用的解决思路,你可以根据业务场景选择:

方案1:导出函数本身,按需获取最新尺寸

这种方式适合不需要实时维护尺寸对象,只在需要时主动获取最新值的场景:

修改工具文件

function sizes() {
  let contentWidth = [...document.body.children].reduce(
    (a, el) => Math.max(a, el.getBoundingClientRect().right), 0) - document.body.getBoundingClientRect().x;
  
  return {
    windowWidth: document.documentElement.clientWidth,
    windowHeight: document.documentElement.clientHeight,
    pageWidth: Math.min(document.body.scrollWidth, contentWidth),
    pageHeight: document.body.scrollHeight,
    screenWidth: window.screen.width,
    screenHeight: window.screen.height,
    pageX: document.body.getBoundingClientRect().x,
    pageY: document.body.getBoundingClientRect().y,
    screenX: -window.screenX,
    screenY: -window.screenY - (window.outerHeight-window.innerHeight),
  }
}
// 导出函数本身,而非执行结果
export default sizes;

修改业务代码

import getSize from "../../utilities/size";

// 可选:添加防抖优化,避免resize高频触发
function debounce(func, delay = 150) {
  let timeoutId;
  return (...args) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func.apply(this, args), delay);
  };
}

window.addEventListener('resize', debounce(() => {
  const latestSize = getSize();
  console.log(latestSize.windowWidth);
}));

// 初始化时获取一次初始尺寸
const initialSize = getSize();
console.log(initialSize.windowWidth);

方案2:导出可变对象,实时更新属性

这种方式适合多个组件/模块需要共用同一套实时尺寸数据的场景,只需要维护一个对象引用:

修改工具文件

// 创建一个可修改的尺寸对象,作为唯一引用
const sizeData = {
  windowWidth: 0,
  windowHeight: 0,
  pageWidth: 0,
  pageHeight: 0,
  screenWidth: 0,
  screenHeight: 0,
  pageX: 0,
  pageY: 0,
  screenX: 0,
  screenY: 0,
};

// 定义更新尺寸的函数
function updateSizes() {
  let contentWidth = [...document.body.children].reduce(
    (a, el) => Math.max(a, el.getBoundingClientRect().right), 0) - document.body.getBoundingClientRect().x;
  
  // 直接更新已有对象的属性,而非创建新对象
  sizeData.windowWidth = document.documentElement.clientWidth;
  sizeData.windowHeight = document.documentElement.clientHeight;
  sizeData.pageWidth = Math.min(document.body.scrollWidth, contentWidth);
  sizeData.pageHeight = document.body.scrollHeight;
  sizeData.screenWidth = window.screen.width;
  sizeData.screenHeight = window.screen.height;
  sizeData.pageX = document.body.getBoundingClientRect().x;
  sizeData.pageY = document.body.getBoundingClientRect().y;
  sizeData.screenX = -window.screenX;
  sizeData.screenY = -window.screenY - (window.outerHeight-window.innerHeight);
}

// 初始化计算一次尺寸
updateSizes();

// 添加防抖后的resize监听,仅绑定一次
function debounce(func, delay = 150) {
  let timeoutId;
  return (...args) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func.apply(this, args), delay);
  };
}
window.addEventListener('resize', debounce(updateSizes));

// 导出这个可变对象
export default sizeData;

修改业务代码

import size from "../../utilities/size";

window.addEventListener('resize', () => {
  // 直接访问对象属性,已经是最新值
  console.log(size.windowWidth);
});

// 初始化时也能拿到正确的初始尺寸
console.log(size.windowWidth);

内容的提问来源于stack exchange,提问作者simonmnt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 07:17:47