实现数字输入框与可拖拽元素的功能绑定
解决可拖拽元素与数字输入框的双向绑定问题
问题诊断
你的核心问题出在三个地方:
- ResizeObserver回调参数错误:你把回调参数命名为
mutations,但ResizeObserver的回调接收的是entries数组,不是MutationObserver的mutations,这导致无法正确获取元素尺寸变化。 - 缺少输入框到拖拽元素的反向同步:当前代码只实现了拖拽→输入框→CSS变量的单向同步,输入框修改后未同步更新拖拽元素宽度,双向绑定失效。
- 宽度计算未考虑盒模型:
.resizable元素的padding会干扰实际可拖拽宽度的计算,需要排除padding影响。
解决方案
以下是修复后的完整代码,关键修改点已标注:
JavaScript 部分
// 处理数字输入框更新CSS变量 const numberInputs = document.querySelectorAll('input[type="number"]'); function updateProp(event) { const uom = this.dataset.uom || ''; const value = this.value + uom; document.documentElement.style.setProperty(`--_${this.name}`, value); // 新增:输入框修改后同步更新拖拽元素宽度 if (this.id === 'measure') { const drag = document.querySelector(".resizable"); drag.style.width = value; } } numberInputs.forEach(input => { input.addEventListener('input', updateProp); }); // 处理拖拽元素更新输入框与CSS变量 const observeMeasure = new ResizeObserver(function(entries) { // 修复:使用entries而非mutations const entry = entries[0]; const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize); // 修复:计算元素内容宽度(排除padding) const contentWidth = entry.contentRect.width; const sizeInRem = contentWidth / rootFontSize; document.documentElement.style.setProperty('--_typecsset-text-measure', `${sizeInRem.toFixed(1)}rem`); const input = document.getElementById('measure'); // 避免循环触发输入事件 if (parseFloat(input.value) !== sizeInRem.toFixed(1)) { input.value = sizeInRem.toFixed(1); } }); const drag = document.querySelector(".resizable"); // 初始化拖拽元素宽度为输入框值 drag.style.width = `${document.getElementById('measure').value}rem`; observeMeasure.observe(drag);
CSS 部分(关键修改)
.resizable { resize: horizontal; /* 替换inline为horizontal,兼容性更好 */ overflow: hidden; /* 替换scroll为hidden,避免不必要滚动条 */ width: var(--_typecsset-text-measure); /* 新增:绑定CSS变量,初始化宽度 */ padding: 0; /* 移除padding,避免影响宽度计算 */ } /* 限制输入框宽度,避免排版错乱 */ #measure { max-width: 100px; }
HTML 部分(无需修改)
保持原HTML结构即可。
关键说明
- ResizeObserver参数修正:使用
entries数组获取尺寸变化的元素信息,确保正确读取contentRect。 - 双向同步逻辑:输入框修改时同步设置
.resizable元素宽度;拖拽元素变化时更新输入框值(加入判断避免循环触发事件)。 - 盒模型优化:移除
.resizable的padding,使用width提升兼容性,避免滚动条干扰拖拽体验。
内容的提问来源于stack exchange,提问作者designtools
相关产品推荐
相关产品推荐

