
本文介绍如何通过 getBoundingClientRect() 精确判断一个可拖拽 div 与其同级兄弟元素是否发生视觉重叠(边界相触即视为重叠),并返回所有重叠元素组成的数组,适用于拖拽布局、碰撞检测等交互场景。
本文介绍如何通过 `getboundingclientrect()` 精确判断一个可拖拽 div 与其同级兄弟元素是否发生视觉重叠(边界相触即视为重叠),并返回所有重叠元素组成的数组,适用于拖拽布局、碰撞检测等交互场景。
在构建拖拽式 UI(如看板、仪表盘或画布编辑器)时,常需实时识别某个元素是否与其他元素发生视觉重叠——例如当用户拖动卡片时,高亮显示其“接触”的目标区域。关键在于:重叠 ≠ 完全覆盖,只要两个元素的边界矩形存在交集(含边线相接),即判定为“触碰”。
以下是一个健壮、零依赖的工具函数 getTouchingDivs,它接收一个 DOM 元素,返回其所有同级 <div> 中与其矩形区域重叠的元素数组:<pre class="brush:php;toolbar:false;">function getTouchingDivs(item) {
if (!item || !item.parentNode) return [];
const itemRect = item.getBoundingClientRect();
const touchingDivs = [];
// 遍历所有同级子元素(不限于 div,但可根据需要过滤)
for (const sibling of item.parentNode.children) {
// 跳过自身,且建议显式过滤非 div 元素(如需严格限定)
if (sibling === item || sibling.nodeType !== Node.ELEMENT_NODE || sibling.tagName !== 'DIV') {
continue;
}
const siblingRect = sibling.getBoundingClientRect();
// 使用标准 AABB(轴对齐包围盒)重叠检测:
// 两矩形不重叠 ⇔ 其中一个完全在另一个的左/右/上/下
const isOverlapping = !(
itemRect.right siblingRect.right ||
itemRect.bottom siblingRect.bottom
);
if (isOverlapping) {
touchingDivs.push(sibling);
}
}
return touchingDivs;
}</pre>
<p>✅ <strong>使用示例:</strong> </p>
<pre class="brush:php;toolbar:false;">const item1 = document.querySelector('#task-1');
const overlappingItems = getTouchingDivs(item1);
console.log(`与 #task-1 重叠的元素:`, overlappingItems);</pre>
<p>⚠️ <strong>注意事项:</strong> </p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill9263" title="Html2md"><img
src="https://img.php.cn/upload/skill/000/000/081/179249945220127.jpg" alt="Html2md" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill9263" title="Html2md" class="overflowclass">Html2md</a>
<p class="overflowclass">使用 Readability + Turndown 将 HTML 页面转换为干净的、Agent 友好的 Markdown。去除导航栏、广告、页脚、Cookie 横幅、社交按钮等干扰元素。支持 URL...</p>
</div>
<a rel="nofollow" href="/xiazai/skill9263" title="Html2md" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<ul>
<li>函数基于 <code>getBoundingClientRect(),返回的是视口坐标系下的绝对位置,自动适配缩放、滚动和 CSS 变换(如 transform: translate),但不支持 transform: rotate 等非轴对齐变换(此时需用 DOMMatrix 或第三方库处理);
overflow: hidden 或 clip-path,视觉裁剪不影响矩形计算结果,逻辑仍按原始尺寸判定; display: none 或 visibility: hidden 元素,可在循环内添加 getComputedStyle(sibling).display !== 'none' && getComputedStyle(sibling).visibility === 'visible' 判断; itemRect 和 siblingRect 缓存,并考虑节流或仅在位置变更后触发检测。该方法简洁、兼容性强(支持所有现代浏览器),是实现轻量级前端碰撞检测的理想起点。










