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

单例ResizeObserver监听多个div时仅触发首个div回调的问题

问题分析与解决:ResizeObserver单例回调绑定错误

问题根源

你的核心问题是ResizeObserverUtility的单例逻辑仅在首次调用getInstance时保存了第一个DIV实例传入的回调,后续创建的DIV实例调用getInstance时,因为单例已存在,不会重新初始化ResizeObserver,导致所有resize事件触发时,始终执行第一个DIV的回调函数,this自然永远指向div-0。

修复方案:让单例支持多元素-回调映射

修改ResizeObserverUtility,通过Map存储每个监听元素对应的回调,确保每个元素的resize事件触发对应实例的逻辑:

class ResizeObserverUtility {
    static getInstance() {
        if (typeof ResizeObserver === 'undefined') {
            console.warn('ResizeObserver is not supported by this browser.');
            return null;
        }

        if (!ResizeObserverUtility.instance) {
            console.log('Creating a new ResizeObserver instance');
            // 用Map存储目标元素与对应回调的映射
            const callbackMap = new Map();
            
            ResizeObserverUtility.instance = new ResizeObserver(entries => {
                for (const entry of entries) {
                    const { height, width } = entry.contentRect;
                    // 根据当前触发resize的元素,取出对应的回调执行
                    const callback = callbackMap.get(entry.target);
                    if (callback) {
                        callback(height, width);
                    }
                }
            });

            // 扩展实例方法,用于注册元素和对应回调
            ResizeObserverUtility.instance.observeWithCallback = function(target, callback) {
                callbackMap.set(target, callback);
                this.observe(target);
            };

            // 可选:添加移除监听时清理回调的方法
            ResizeObserverUtility.instance.unobserveWithCallback = function(target) {
                callbackMap.delete(target);
                this.unobserve(target);
            };
        }
        return ResizeObserverUtility.instance;
    }
}

然后修改DIV构造函数中的调用方式:

// 在DIV构造函数内
const util = ResizeObserverUtility.getInstance();
// 使用新增的observeWithCallback方法,传入当前元素和绑定好this的回调
util.observeWithCallback(this._domNode, (height, width) => this.exampleFunc(height, width));

方案优势

  • 保留了应用级单例的性能优势,避免创建多个ResizeObserver实例
  • 通过Map建立元素与回调的一一对应,确保每个元素的resize事件触发自身实例的逻辑
  • 箭头函数保证了exampleFunc中的this正确指向当前DIV实例

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 08:13:11