如何基于另一元素的getBoundingClientRectAsync值计算窗口宽度
能否基于虚拟DOM中元素的
getBoundingClientRectAsync返回值计算视口或窗口宽度? 现有问题背景
你当前使用coordsTrigger.left + coordsTrigger.width计算窗口宽度的逻辑是错误的,这个值仅能得到触发元素本身的右边缘坐标,无法代表整个视口宽度。
而你遇到的window.innerWidth不随resize更新的问题,确实是amp-script的web worker运行环境限制导致的:worker线程的window对象属性是初始化时同步的,不会随主线程视口变化实时更新。
可行解决方案
你可以借助amp-script内占满视口的参考元素,通过getBoundingClientRectAsync拿到实时视口宽度,具体实现如下:
步骤1:新增视口参考元素
在amp-script标签内新增一个隐藏的、宽度占满整个视口的参考元素:
<amp-script layout="fill" script="tooltip-async"> <span class="tooltip-trigger"></span> <!-- 新增参考元素 --> <span class="viewport-ref" style="position:fixed;left:0;top:0;width:100vw;visibility:hidden;pointer-events:none;"></span> </amp-script>
步骤2:封装视口宽度获取方法
调用参考元素的getBoundingClientRectAsync,返回的width值就是当前实时视口宽度:
let button = document.querySelector('.tooltip-trigger'); // 缓存视口宽度,避免重复查询 let viewportWidth = 0; // 获取实时视口宽度 async function updateViewportWidth() { const ref = document.querySelector('.viewport-ref'); const coords = await ref.getBoundingClientRectAsync(); viewportWidth = coords.width; } // 初始化和resize时更新宽度 updateViewportWidth(); window.addEventListener('resize', updateViewportWidth); async function addTooltip(event) { tooltipElem = document.createElement('span'); document.body.appendChild(tooltipElem); let coordsTrigger = await target.getBoundingClientRectAsync(); // 直接使用缓存的实时视口宽度即可 console.log(viewportWidth); // 后续右偏移计算逻辑直接用viewportWidth即可 }
该方案的原理是参考元素的尺寸和实际视口完全绑定,getBoundingClientRectAsync返回的是主线程同步的最新元素坐标,不会出现缓存问题,完全适配amp-script的web worker运行环境。
内容的提问来源于stack exchange,提问作者la_petite_kozel
相关产品推荐
相关产品推荐

