你能用 JavaScript 判断一个元素是不是正在接触另一个元素吗?
Posted
技术标签:
【中文标题】你能用 JavaScript 判断一个元素是不是正在接触另一个元素吗?【英文标题】:Can you tell if one element is touching another using JavaScript?你能用 JavaScript 判断一个元素是否正在接触另一个元素吗? 【发布时间】:2015-07-07 03:41:05 【问题描述】:我想使用 javascript 检查一个div
元素(可以拖动)是否接触到另一个div
元素。
这是一些代码:
<div id="draggable" style="position: absolute; top: 100px; left: 200px; background-color: red; width: 100px; height: 100px;"></div>
<div style="background-color: green; width: 100px; height: 100px;"></div>
这个可以吗?
如果有,怎么做?
编辑:我不想使用 jQuery,只想使用普通的旧 JavaScript!
【问题讨论】:
check collision between certain divs?的可能重复 通过计算元素顶部/左侧和宽度/高度你可以做到:) ***.com/questions/442404/… PS:上面的评论和我说的一样......哦,好吧......:D跨度> 【参考方案1】:更完整的解决方案
下面是对this answer 中的重叠检测函数的“普通旧 JavaScript”重写,改写为标题为“jQuery/Javascript collision detection”的问题。
两者之间唯一真正的区别是替换使用jQuery获取元素位置和宽度来计算边界框。
令人惊讶的是,原生 JavaScript 使用得到良好支持的 (IE4+) Element.getBoundingClientRect()
方法简化了这项任务,该方法返回创建 getPositions
函数返回的位置矩阵所需的四个值。
我为这些框添加了一个单击处理程序,以简单演示如何使用该函数将目标(单击、拖动等)元素与一组选定元素进行比较。 不过,我承认 jQuery 使 DOM 选择和事件绑定比原生 JS 更容易。
var boxes = document.querySelectorAll('.box');
boxes.forEach(function (el)
if (el.addEventListener)
el.addEventListener('click', clickHandler);
else
el.attachEvent('onclick', clickHandler);
)
var detectOverlap = (function ()
function getPositions(elem)
var pos = elem.getBoundingClientRect();
return [[pos.left, pos.right], [pos.top, pos.bottom]];
function comparePositions(p1, p2)
var r1, r2;
if (p1[0] < p2[0])
r1 = p1;
r2 = p2;
else
r1 = p2;
r2 = p1;
return r1[1] > r2[0] || r1[0] === r2[0];
return function (a, b)
var pos1 = getPositions(a),
pos2 = getPositions(b);
return comparePositions(pos1[0], pos2[0]) && comparePositions(pos1[1], pos2[1]);
;
)();
function clickHandler(e)
var elem = e.target,
elems = document.querySelectorAll('.box'),
elemList = Array.prototype.slice.call(elems),
within = elemList.indexOf(elem),
touching = [];
if (within !== -1)
elemList.splice(within, 1);
for (var i = 0; i < elemList.length; i++)
if (detectOverlap(elem, elemList[i]))
touching.push(elemList[i].id);
if (touching.length)
console.log(elem.id + ' touches ' + touching.join(' and ') + '.');
alert(elem.id + ' touches ' + touching.join(' and ') + '.');
else
console.log(elem.id + ' touches nothing.');
alert(elem.id + ' touches nothing.');
#box1
background-color: LightSeaGreen;
#box2
top: 25px;
left: -25px;
background-color: SandyBrown;
#box3
left: -50px;
background-color: SkyBlue;
#box4
background-color: SlateGray;
.box
position: relative;
display: inline-block;
width: 100px;
height: 100px;
color: White;
font: bold 72px sans-serif;
line-height: 100px;
text-align: center;
cursor: pointer;
.box:hover
color: Black;
<p>Click a box to see which other boxes are detected as touching it.<br />
<em>If no alert dialog box appears, open your console to view messages.</em></p>
<div class="box" id="box1">1</div>
<div class="box" id="box2">2</div>
<div class="box" id="box3">3</div>
<div class="box" id="box4">4</div>
【讨论】:
是的。请参阅this example with 99 overlapping boxes 尽管在某些时候您可能会开始看到明显的性能下降,因为此解决方案会循环遍历所有选定的元素(在本例中为class="box"
),获取每个元素的位置并将其与目标元素进行比较。
您可以通过在comparePostions()
中使用Math.min(p1, p2)
来进一步收紧此代码。
@JesseJamesBurton 比较是一样的,但是赋值不同。我可以存储比较的结果,并在每个表达式的三进制中使用它来防止冗余操作。
啊,好吧,我明白了,所以基本上对于每次比较,您总是将 1 个项目分配给 r1,将一个项目分配给 r2,然后正确吗?感谢您的澄清!
太棒了!这完全有道理:)【参考方案2】:
更新:我现在意识到这仅考虑了目标元素左上角的交点,因此不能提供完整的解决方案。但我会把它留给后代,以防有人发现它对其他目的有用。
使用element.getBoundingClientRect()
和document.elementFromPoint()
您可以使用element.getClientBoundingRect()
(src) 获取目标(单击、拖动等)元素的位置。
暂时隐藏目标元素,然后使用document.elementFromPoint(x, y)
(src) 获取该位置的最顶层元素,然后检查它的类名以进行比较(如果您可以比较任何属性或属性,更喜欢)。
通过此方法实现跨浏览器兼容行为 阅读:document.elementFromPoint – a jQuery solution (你不知道 必须使用 jQuery 来实现这个结果。该方法可以 在纯 JS 中复制。)
附录:
我只展示了用于检测重叠的功能,而不是展示拖放或拖动移动功能,因为不清楚您正在尝试实现哪些功能(如果有的话)并且还有其他答案展示如何完成各种拖动模式。
在任何情况下,您都可以将下面的detectCollision()
函数与任何拖动解决方案结合使用。
var box2 = document.getElementById('box2'),
box3 = document.getElementById('box3');
box2.onclick = detectCollision;
box3.onclick = detectCollision;
function detectCollision(e)
var elem = e.target,
elemOffset = elem.getBoundingClientRect(),
elemDisplay = elem.style.display;
// Temporarily hide element
elem.style.display = 'none';
// Check for top-most element at position
var topElem = document.elementFromPoint(elemOffset.left, elemOffset.top);
// Reset element's initial display value.
elem.style.display = elemDisplay;
// If a top-most element is another box
if (topElem.className.match(/box/))
alert(elem.id + " is touching " + topElem.id);
else
alert(elem.id + " isn't touching another box.");
;
#box1
background-color: LightSeaGreen;
#box2
top: 25px;
left: -25px;
background-color: SandyBrown;
#box3
background-color: SkyBlue;
.box
position: relative;
display: inline-block;
width: 100px;
height: 100px;
.clickable
cursor: pointer;
<div class="box" id="box1"></div>
<div class="box clickable" id="box2"></div>
<div class="box clickable" id="box3"></div>
【讨论】:
以上是关于你能用 JavaScript 判断一个元素是不是正在接触另一个元素吗?的主要内容,如果未能解决你的问题,请参考以下文章