如何在JavaScript中获取各浏览器通用的元素准确宽度?
问题描述
我希望获取某元素的宽度,以此将另一个元素的宽度设置得与之完全一致,但无论使用哪种方法,不同浏览器返回的结果都存在差异。
具体场景:想让输入框宽度与选中的option一致,使用了以下可正常运行的JavaScript代码:
var inputFields = document.querySelectorAll(".my-input-field"); // Resize on change inputFields.forEach(function(element) { element.addEventListener("change", function() { resizeSelect(element); }); }); function resizeSelect(sel) { let tempOption = document.createElement('option'); tempOption.textContent = sel.options[sel.selectedIndex].textContent; let tempSelect = document.createElement('select'); tempSelect.style.visibility = "hidden"; tempSelect.style.position = "fixed" tempSelect.appendChild(tempOption); sel.after(tempSelect); sel.style.width = (parseInt(window.getComputedStyle(tempSelect).width) - 25) + 'px'; tempSelect.remove(); }
使用window.getComputedStyle(tempSelect).width获取宽度时,Firefox返回201px,Edge返回196px,尚未测试更多浏览器。这种差异的原因是什么?
我还尝试了tempSelect.offsetWidth和tempSelect.getBoundingClientRect()['width'],结果一致。
是否存在可在各浏览器中获取元素准确宽度的通用解决方案?
补充:我的select元素应用了以下CSS样式:
.advanced-search-select-and-input{ color: rgb(80, 80, 80); background: rgb(250, 250, 250); border: none; outline: none; -webkit-appearance: none; } .advanced-search-select-and-input::-ms-expand { /* To not show dropdown arrow in IE etc */ display: none; }
问题原因
不同浏览器对select元素的默认盒模型、内边距、隐性内部布局样式的计算逻辑存在差异,即便移除了默认外观和下拉箭头,仍会残留浏览器特有的布局规则。另外,各浏览器字体渲染引擎的字符间距、字体度量方式不同,也会导致文本宽度计算出现偏差,最终反映在元素整体宽度上。
通用解决方案
1. 用隐藏span替代select测量文本宽度
避开select元素的浏览器默认样式干扰,改用纯文本容器测量选中选项的文本宽度,精度更高:
function resizeSelect(sel) { const selectedText = sel.options[sel.selectedIndex].textContent; const tempSpan = document.createElement('span'); // 复制目标元素的字体、内边距等样式,保证测量和实际显示一致 const selStyles = window.getComputedStyle(sel); tempSpan.style.font = selStyles.font; tempSpan.style.padding = selStyles.padding; tempSpan.style.border = selStyles.border; tempSpan.style.visibility = 'hidden'; tempSpan.style.position = 'fixed'; tempSpan.textContent = selectedText; sel.after(tempSpan); const textWidth = tempSpan.getBoundingClientRect().width; // 10px为预留的输入框操作空间,可根据实际样式调整 sel.style.width = `${textWidth + 10}px`; tempSpan.remove(); }
2. 统一盒模型规则
为相关元素设置box-sizing: border-box,确保宽度计算包含内边距和边框,避免浏览器因盒模型差异导致的宽度偏差:
.advanced-search-select-and-input { box-sizing: border-box; color: rgb(80, 80, 80); background: rgb(250, 250, 250); border: none; outline: none; -webkit-appearance: none; } .advanced-search-select-and-input::-ms-expand { display: none; }
3. 移除硬编码宽度偏移
代码中-25px的固定偏移是跨浏览器差异的诱因之一,不同浏览器默认控件内部间距不同。建议基于文本宽度动态调整,去掉固定偏移值,或根据实际样式动态计算需要的额外空间。
内容的提问来源于stack exchange,提问作者eligolf
相关产品推荐
相关产品推荐

