Можете ли вы сказать, что один элемент касается другого с помощью JavaScript?

Я хочу использовать JavaScript для проверки того, является ли один элемент div (который можно перетаскивать) касаться другого элемента div .

Вот какой код:

 

Это можно сделать?

Если да, то как?

Изменить: я не хочу использовать jQuery, просто старый JavaScript!

Более полное решение

Ниже приведена «простая старая версия JavaScript» для функции обнаружения перекрытия, найденная в этом ответе на вопрос « jQuery / Javascript collision detection ».

Единственная реальная разница между ними заключается в замене использования jQuery для получения позиции элемента и ширины для вычисления ограничивающей frameworks.

Удивительно, но нативный JavaScript упрощает эту задачу с помощью хорошо поддерживаемого метода (IE4 +) Element.getBoundingClientRect() , который возвращает четыре значения, необходимые для создания матрицы положения, возвращаемой функцией getPositions .

Я добавил обработчик кликов для ящиков как простую демонстрацию того, как вы можете использовать эту функцию для сравнения элемента target (clicked, dragged, etc.) с набором выбранных элементов. Однако я уступлю, что 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; r1 = p1[0] < p2[0] ? p1 : p2; r2 = p1[0] < p2[0] ? p2 : 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; } 
 

Click a box to see which other boxes are detected as touching it.
If no alert dialog box appears, open your console to view messages.

1
2
3
4

Обновление: теперь я понимаю, что это только учет для пересечения верхнего левого угла целевого элемента и, следовательно, не дает полного решения. Но я оставлю его для потомков, если кто-то найдет его полезным для других целей.


Используйте element.getBoundingClientRect() и document.elementFromPoint()

  1. Вы можете использовать element.getClientBoundingRect() ( src ), чтобы получить позицию элемента target ( element.getClientBoundingRect() , etc.).

  2. Временно скройте целевой элемент, затем используйте document.elementFromPoint(x, y) ( src ), чтобы получить самый верхний элемент в этой позиции, а затем проверьте его имя classа для сравнения (вместо этого вы можете сравнить любой атрибут или свойство, если вы предпочитают).

    Чтобы добиться совместимости с кросс-браузером этого метода, прочитайте: document.elementFromPoint – решение jQuery (вам не нужно использовать 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; }