@m4zuper Ну например на скрине видно , adbtc
Как одним действием найти видимые элементы на странице
-
Запросить количество элементов и потом перебирать циклом на проверку каждого, виден ли элемент на странице, такой способ не предлагать, это очень долго.
Как можно одним действием, получить количество видимых элементов на странице? Например на странице есть 5к элементов, 500 всего видимых, получить не все 5к, а именно 500 сразу в список
-
IntersectionObserver, надо тестить, но работать будет не сильно быстрее, я думаю. И все равно без цикла не обойтись, ну или я не знаю как.
Решение в лоб отработало на этой странице почти мгновенно. Но в нем нет проверки что элемент не перекрыт чем-нибудь, не сливается с фоном ну или что имелось в виду под понятием "видимый". Техники понять это обсуждались на этом форуме.
// Получаем все элементы на странице const allElements = document.body.getElementsByTagName('*'); // Функция для проверки, видим ли элемент const isVisible = (elem) => { const rect = elem.getBoundingClientRect(); const viewHeight = Math.max(window.innerHeight, document.documentElement.clientHeight); const viewWidth = Math.max(window.innerWidth, document.documentElement.clientWidth); // Проверяем, находится ли элемент в видимой части окна просмотра return !(rect.bottom < 0 || rect.top > viewHeight || rect.right < 0 || rect.left > viewWidth); }; // Фильтруем видимые элементы const visibleElements = Array.from(allElements).filter(isVisible); console.log(visibleElements.length); // Количество видимых элементов console.log(visibleElements); // Массив видимых элементов -
@sergerdn said in Как одним действием найти видимые элементы на странице:
IntersectionObserver, надо тестить, но работать будет не сильно быстрее, я думаю. И все равно без цикла не обойтись, ну или я не знаю как.
Решение в лоб отработало на этой странице почти мгновенно. Но в нем нет проверки что элемент не перекрыт чем-нибудь, не сливается с фоном ну или что имелось в виду под понятием "видимый". Техники понять это обсуждались на этом форуме.
// Получаем все элементы на странице const allElements = document.body.getElementsByTagName('*'); // Функция для проверки, видим ли элемент const isVisible = (elem) => { const rect = elem.getBoundingClientRect(); const viewHeight = Math.max(window.innerHeight, document.documentElement.clientHeight); const viewWidth = Math.max(window.innerWidth, document.documentElement.clientWidth); // Проверяем, находится ли элемент в видимой части окна просмотра return !(rect.bottom < 0 || rect.top > viewHeight || rect.right < 0 || rect.left > viewWidth); }; // Фильтруем видимые элементы const visibleElements = Array.from(allElements).filter(isVisible); console.log(visibleElements.length); // Количество видимых элементов console.log(visibleElements); // Массив видимых элементовВажный момент, этот способ не определит видимые элементы внутри фреймов
-
@sergerdn said in Как одним действием найти видимые элементы на странице:
IntersectionObserver, надо тестить, но работать будет не сильно быстрее, я думаю. И все равно без цикла не обойтись, ну или я не знаю как.
Решение в лоб отработало на этой странице почти мгновенно. Но в нем нет проверки что элемент не перекрыт чем-нибудь, не сливается с фоном ну или что имелось в виду под понятием "видимый". Техники понять это обсуждались на этом форуме.
// Получаем все элементы на странице const allElements = document.body.getElementsByTagName('*'); // Функция для проверки, видим ли элемент const isVisible = (elem) => { const rect = elem.getBoundingClientRect(); const viewHeight = Math.max(window.innerHeight, document.documentElement.clientHeight); const viewWidth = Math.max(window.innerWidth, document.documentElement.clientWidth); // Проверяем, находится ли элемент в видимой части окна просмотра return !(rect.bottom < 0 || rect.top > viewHeight || rect.right < 0 || rect.left > viewWidth); }; // Фильтруем видимые элементы const visibleElements = Array.from(allElements).filter(isVisible); console.log(visibleElements.length); // Количество видимых элементов console.log(visibleElements); // Массив видимых элементовНапример, кнопка, если нажать на кнопку, всплывет меню с ссылками (это не видимые ссылки), т.е элемент в коде есть, но по нему кликнуть нельзя, пока не нажать на кнопку меню, чтобы всплыло подменю
-
window.scrollTo(0, 0) var bodyRect = document.body.getBoundingClientRect(); var items = Array.prototype.slice.call( document.querySelectorAll('*') ).map(function(element) { var rect=element.getBoundingClientRect(); return { element: element, include: (element.tagName === "BUTTON" || element.tagName === "A" || (element.onclick != null) || window.getComputedStyle(element).cursor == "pointer"), rect: {left: Math.max(rect.left - bodyRect.x, 0), top: Math.max(rect.top - bodyRect.y, 0), right: Math.min(rect.right - bodyRect.x, document.body.clientWidth), bottom: Math.min(rect.bottom - bodyRect.y, document.body.clientHeight)}, text: element.textContent.trim().replace(/\s{2,}/g, ' ') }; }).filter(item => item.include && ((item.rect.right - item.rect.left) * (item.rect.bottom - item.rect.top) >= 20)); // Only keep inner clickable items items = items.filter(x => !items.some(y => x.element.contains(y.element) && !(x == y))) // Lets create a floating border on top of these elements that will always be visible items.forEach(function(item) { newElement = document.createElement("div"); newElement.style.outline = "2px dashed rgba(255,0,0,.75)"; newElement.style.position = "absolute"; newElement.style.left = item.rect.left + "px"; newElement.style.top = item.rect.top + "px"; newElement.style.width = (item.rect.right - item.rect.left) + "px"; newElement.style.height = (item.rect.bottom - item.rect.top) + "px"; newElement.style.pointerEvents = "none"; newElement.style.boxSizering = "border-box"; newElement.style.zIndex = 2147483647; document.body.appendChild(newElement); })иногда ложно срабатывает но в целом рабочее:
