WordPress Elementor三列网格中遍历HTMLCollection获取offsetHeight值异常重复问题
这个问题我太熟了!和Elementor三列Grid的自动等高列逻辑直接相关,咱们一步步拆解:
为什么会出现三组重复的offsetHeight?
Elementor的三列Grid默认会开启「等高列」功能——它会在页面加载完成后,用JS计算每一行中最高的那个article的高度,然后把这个高度统一设置给该行的三个article元素,保证同一行的列视觉上对齐。
你获取offsetHeight的时机,刚好是Elementor的这个自动等高逻辑执行之后,所以同一行的三个article高度都被改成了该行最高值,就出现了[362,362,362,257,257,257,...]这种三组重复的结果。而且这个问题和你用Array.from转HTMLCollection无关,哪怕你直接遍历HTMLCollection,得到的结果也是一样的。
解决方案
根据你的需求,分两种情况处理:
情况1:需要获取元素原始的未修改高度
方法一:关闭Elementor的等高列功能
在Elementor编辑器里选中这个Grid元素,找到「布局」设置面板,关掉「等高列」(不同Elementor版本可能叫「Equal Height」或者「统一高度」)。之后再刷新页面,你获取的offsetHeight就是每个article原本的高度了。方法二:在Elementor修改高度前捕获原始值
Elementor的等高逻辑一般是在window.load或者DOMContentLoaded事件后期执行的,你可以把你的代码放在更早的时机运行,比如:document.addEventListener('DOMContentLoaded', function() { const articles = document.querySelectorAll('article'); // 此时Elementor还没修改高度,能拿到原始值 const originalHeights = Array.from(articles).map(article => article.offsetHeight); console.log(originalHeights); }, { capture: true }); // 用捕获阶段提前执行或者用
MutationObserver监听article的style变化,在height被修改前记录原始值。
情况2:要保留Elementor的等高效果,同时获取原始高度
如果既要页面视觉上的等高列,又需要每个元素的原始高度做后续处理,可以先保存原始高度,再让Elementor执行等高逻辑:
document.addEventListener('DOMContentLoaded', function() { const articles = document.querySelectorAll('article'); // 保存原始高度(用getBoundingClientRect更准确,不受后续style修改影响) const originalHeights = Array.from(articles).map(article => { return article.getBoundingClientRect().height; }); // 等Elementor执行完等高逻辑后,再基于原始值做处理 setTimeout(() => { console.log('原始高度:', originalHeights); console.log('Elementor修改后的高度:', Array.from(articles).map(a => a.offsetHeight)); }, 1000); // 延迟时间可以根据页面加载速度调整,或者用更可靠的监听方式 });
注意:offsetHeight是元素的可见高度(包含边框、内边距),scrollHeight是元素内容的总高度(包含溢出部分),根据你的实际需求选择合适的属性。
内容的提问来源于stack exchange,提问作者Noloxe

