Получить элемент из точки, когда у вас есть перекрывающиеся элементы?
Вы можете использовать это, чтобы найти элемент документа в заданной точке
document.elementFromPoint(x, y);
Что вы можете сделать, если в точке есть перекрывающиеся элементы? (Я знаю, что это не отличный способ сделать что-то - попытку хакерского обходного пути для ошибки до крайнего срока).
Ответы
Ответ 1
Как я думаю, вы уже знаете, document.elementFromPoint(x, y);
возвращает только самый верхний элемент, который перекрывает эту точку.
Если то, что вы пытаетесь сделать, это найти все элементы, которые накладываются на заданную точку, даже элементы за другими элементами, тогда я не знаю о какой-либо функции DOM, которая сделает это за вас. Возможно, вам придется писать свои собственные.
Несколько хакерской версией было бы вызвать elementFromPoint(x,y)
, помнить этот элемент DOM, затем скрыть этот элемент с display: none
, а затем вызвать elementFromPoint(x,y)
снова, пока все, что вы получите, не является телом, а затем восстановите элементы вы спрятались.
Менее хакерской версией будет цикл, хотя все объекты на странице, и сравните их смещение/высоту/ширину на странице с вашей точкой.
Вот один из способов сделать это:
function getAllElementsFromPoint(x, y) {
var elements = [];
var display = [];
var item = document.elementFromPoint(x, y);
while (item && item !== document.body && item !== window && item !== document && item !== document.documentElement) {
elements.push(item);
display.push(item.style.display);
item.style.display = "none";
item = document.elementFromPoint(x, y);
}
// restore display property
for (var i = 0; i < elements.length; i++) {
elements[i].style.display = display[i];
}
return elements;
}
Рабочая демонстрация: http://jsfiddle.net/jfriend00/N9pu9/
Ответ 2
Если вы хотите найти все элементы DOM, которые перекрывают точку, вы можете просто использовать document.elementsFromPoint(), который возвращает массив всех элементов, найденных в указанной точке (очевидно, упорядоченный сверху вниз относительно области просмотра, т.е.: если есть оверлей, он будет отображаться первым в массиве)
Ответ 3
Не уверен, по какой причине был задан начальный вопрос, но если вам нужно обнаружить элемент, который в настоящее время перетаскивается с помощью элемента touch или mouse, вы можете установить pointer-events: none;
на перетаскиваемом элементе. Когда вы это сделаете, document.elementFromPoint()
будет игнорировать текущий перетаскиваемый элемент и вернуть его под ним.
Ответ 4
Простое решение
В случае, когда $e
является перекрывающимся элементом, e
является событием
$e.style.display = 'none';
var b = document.elementFromPoint(e.clientX,e.clientY);
$e.style.display = 'block';
Ответ 5
Итак, насколько я вижу, этот ответ - fooobar.com/info/8180598/... - был бы идеальным, но, к сожалению, document.elementsFromPoint()
не работает в IE11.
В противном случае код в этом ответе - fooobar.com/info/8180598/... кажется, работает в большинстве современных браузеров, включая IE11, но есть ошибка, при которой определенные элементы DOM дублируются в массиве, возвращаемом функцией,
Однако, если кто-то ищет shim document.elementsFromPoint()
, хороший пример можно найти здесь:
https://gist.github.com/oslego/7265412
Скопировано здесь для удобства:
function elementsFromPoint(x,y) {
var elements = [], previousPointerEvents = [], current, i, d;
// get all elements via elementFromPoint, and remove them from hit-testing in order
while ((current = document.elementFromPoint(x,y)) && elements.indexOf(current)===-1 && current != null) {
// push the element and its current style
elements.push(current);
previousPointerEvents.push({
value: current.style.getPropertyValue('pointer-events'),
priority: current.style.getPropertyPriority('pointer-events')
});
// add "pointer-events: none", to get to the underlying element
current.style.setProperty('pointer-events', 'none', 'important');
}
// restore the previous pointer-events values
for(i = previousPointerEvents.length; d=previousPointerEvents[--i]; ) {
elements[i].style.setProperty('pointer-events', d.value?d.value:'', d.priority);
}
// return our results
return elements;
}