Проблемы:
Реальная проблема заключается в том, что существует так много способов, которые могут быть покрыты элемент. Например, элемент, покрытый четырьмя другими элементами, и просто пространство открыто посередине? Пример того, что я имею в виду:
Если предположить, что красный прямоугольник является элементом, о котором идет речь, небольшой блок, прямо в центре является прямым видом элемента.
Из-за этих проблем может возникнуть очень «дорого», чтобы определить, имеет ли элемент какую-либо нависшую область.
Решение:
Я придумал решение с использованием boundingClientRect
, document.elementFromPoint
и скроллинг документа. Он пытается быстро определить, проверив 4 угла соответствующего элемента, а затем, если они вернутся назад, начните проверять весь элемент с помощью определенной «точности».
UPDATE:
Я добавил в пути, чтобы проверить элементы, которые даже не в окне просмотра. Это работает, пытаясь прокрутить элемент, запустить проверку, а затем прокрутить назад до предыдущей позиции до начала проверки. Это происходит так быстро, что никаких видимых скачков не происходит.
function getOffset(el) {
el = el.getBoundingClientRect();
return {
left: el.left + window.scrollX,
top: el.top + window.scrollY
}
}
function isElementHoverable(element) {
var pageX = window.scrollX;
var pageY = window.scrollY;
var elementXY = getOffset(element);
var accuracy = 1;
var canBeHovered = false;
window.scrollTo(elementXY.left, elementXY.top);
var box = element.getBoundingClientRect();
// try the 4 corners first
if (
element == document.elementFromPoint(box.left, box.top) ||
element == document.elementFromPoint(box.left, box.bottom - 1) ||
element == document.elementFromPoint(box.right - 1, box.top) ||
element == document.elementFromPoint(box.right - 1, box.bottom - 1)
) {
canBeHovered = true;
}
loop1:
for (let i = box.left; i < box.right; i += accuracy) {
for (let j = box.top; j < box.bottom; j += accuracy) {
if (element == document.elementFromPoint(i, j)) {
canBeHovered = true;
break loop1;
}
}
}
window.scrollTo(pageX, pageY); // Scroll back to the original position
return canBeHovered;
}
I worked up an actual example on JSFiddle (пример был обновлен, чтобы отразить элементы прокручивать страницу вниз), в комплекте с парой испытаний. Вам нужно будет открыть консоль браузера, чтобы просмотреть результаты тестов. Вероятно, вы также захотите проверить это в Chrome или Firefox, так как я не тестировал это за пределами этого.
Несколько вещей, чтобы помнить:
Если проверка 4 угла выходит из строя, то он становится дорогим, чтобы проверить остальную часть элемента. Чем меньше число «точность», тем дороже оно получается. Это число определяет, как часто запускать проверку. Так что если точность 1
, то она будет проверять каждый 1px. Если число равно 10
, то он проверяет каждые 10 пикселей на оси X и Y.
Следует отметить, что практически нет способов узнать варианты элементов на странице. Вы отмечаете в комментарии, что некоторые элементы могут исчезнуть, которые были «блокированы» во время проверки, но не во время взаимодействия пользователя.Невозможно узнать об этой функциональности, кроме AI. Однако эта функция предназначена для вашего выбора, а не только для загрузки страницы.
Я не думаю, что это возможно, потому что каждый элемент может зависнуть. Элементы не знают об их отношениях друг с другом, поэтому вы не можете их просить. –
@AniketSahrawat да, но это не ответит на вопрос OP о прозрачных элементах. –
@charlieg когда-нибудь вы можете что-то сделать, используя document.elementFromPoint (x, y), но мне хотелось бы что-то более полное – JaneCC