如何在Knockout JS+OJET中监听div宽度变化并触发wrapLines函数?
解决方案:使用ResizeObserver监听元素宽度变化
针对Knockout JS + OJET的视图-视图模型架构,要监听指定div的所有宽度变化场景(窗口缩放、菜单折叠/展开等),可以使用浏览器原生的ResizeObserver API,这是专门用于监听元素尺寸变化的方案,能覆盖所有触发元素宽高改变的场景,替代仅能监听窗口的window.resize事件。
实现步骤与代码示例
1. 视图层(HTML)
确保目标div的id为X,如果是OJET组件包裹的元素,也要保证最终渲染的DOM节点id正确:
<div id="X" data-bind="ojComponent: { ... }"> <!-- 内容 --> </div>
2. 视图模型层
在OJET的视图模型中,利用组件生命周期钩子(如attached)初始化ResizeObserver,并在detached钩子中销毁监听,避免内存泄漏:
define(['knockout', 'ojs/ojcomponentcore'], function(ko) { function ViewModel() { const self = this; // 目标元素的引用 self.targetElement = null; // ResizeObserver实例 self.resizeObserver = null; // 要执行的wrapLines函数 self.wrapLines = function(width) { // 这里写你的业务逻辑,比如根据新宽度处理文本换行等 console.log('Div宽度变化为:', width); }; // 初始化ResizeObserver self.initResizeObserver = function() { self.targetElement = document.getElementById('X'); if (!self.targetElement) return; self.resizeObserver = new ResizeObserver(entries => { for (let entry of entries) { // 获取当前元素的宽度(content-box尺寸) const newWidth = entry.contentRect.width; // 调用wrapLines函数 self.wrapLines(newWidth); } }); // 开始监听目标元素 self.resizeObserver.observe(self.targetElement); }; // OJET组件挂载完成后初始化监听 self.attached = function() { self.initResizeObserver(); }; // OJET组件卸载时销毁监听 self.detached = function() { if (self.resizeObserver && self.targetElement) { self.resizeObserver.unobserve(self.targetElement); self.resizeObserver.disconnect(); } }; } return new ViewModel(); });
关键说明
ResizeObserver会监听元素的所有尺寸变化,包括但不限于:窗口缩放、父元素布局变化、菜单折叠/展开导致的空间变化、元素自身内容变化等,完美覆盖你的需求。- 必须在元素渲染完成后(如OJET的
attached钩子、Knockout的afterRender绑定)初始化监听,否则无法获取到目标DOM节点。 - 组件卸载时一定要调用
unobserve和disconnect销毁Observer,防止内存泄漏。 - 如果你需要监听元素的边框盒(border-box)尺寸,可以用
entry.borderBoxSize代替contentRect.width,根据实际业务选择。
内容的提问来源于stack exchange,提问作者new_here
相关产品推荐
相关产品推荐

