有什么方法,我可以检查如果一个元素是可见的纯JS(没有jQuery) ?
因此,给定一个DOM元素,我如何检查它是否可见?我试着:
window.getComputedStyle(my_element)['display']);
但这似乎并不奏效。我想知道我应该检查哪些属性。我想到了:
display !== 'none'
visibility !== 'hidden'
还有我可能漏掉的吗?
有什么方法,我可以检查如果一个元素是可见的纯JS(没有jQuery) ?
因此,给定一个DOM元素,我如何检查它是否可见?我试着:
window.getComputedStyle(my_element)['display']);
但这似乎并不奏效。我想知道我应该检查哪些属性。我想到了:
display !== 'none'
visibility !== 'hidden'
还有我可能漏掉的吗?
当前回答
如果你正在抓取网站,一个非常低效的方法对我来说是突出显示任何元素,然后截图,然后检查截图是否发生了变化。
//Screenshot
function makeSelected(element){
let range = new Range()
range.selectNode(element)
let selection = window.getSelection()
selection.removeAllRanges()
selection.addRange(range)
}
// screenshot again and check for diff
其他回答
下面是一个(纯纯的JS)函数,它执行大量的检查,确保给定的元素对用户可见:
function isVisible(element) {
// Check if the element is null or undefined
if (!element) return false;
// Get the element's bounding client rect
const boundingRect = element.getBoundingClientRect();
// Check if the element has a positive width and height
if (boundingRect.width <= 0 || boundingRect.height <= 0) return false;
// Check if the element's top and left values are within the viewport
const top = boundingRect.top;
const left = boundingRect.left;
const viewportWidth = window.innerWidth || document.documentElement.clientWidth;
const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
if (top > viewportHeight || left > viewportWidth) return false;
// Check if the element's right and bottom values are within the viewport
const right = boundingRect.right;
const bottom = boundingRect.bottom;
if (right < 0 || bottom < 0) return false;
// Check if the element is hidden by the overflow property
const parentNode = element.parentNode;
if (parentNode && getComputedStyle(parentNode).overflow === 'hidden') {
const parentRect = parentNode.getBoundingClientRect();
if (top < parentRect.top || bottom > parentRect.bottom || left < parentRect.left || right > parentRect.right) {
return false;
}
}
const elementComputedStyle = getComputedStyle(element);
// Check if the element has a z-index of less than 0
const zIndex = elementComputedStyle.zIndex;
if (zIndex < 0) return false;
// Check if the element has a display value of 'none' or an opacity of 0
const display = elementComputedStyle.display;
const opacity = elementComputedStyle.opacity;
if (display === 'none' || opacity === '0') return false;
// Check if the element is hidden by an ancestor element with a display value of 'none' or an opacity of 0
let ancestorElement = element.parentElement;
while (ancestorElement) {
const ancestorComputedStyle = getComputedStyle(ancestorElement);
const ancestorDisplay = ancestorComputedStyle.display;
const ancestorOpacity = ancestorComputedStyle.opacity;
if (ancestorDisplay === 'none' || ancestorOpacity === '0') return false;
ancestorElement = ancestorElement.parentElement;
}
// Initialize a variable to keep track of whether the element is obscured by another element
let obscured = false;
// Check if the element is obscured by another element according to its position
if (elementComputedStyle.position === 'absolute' || elementComputedStyle.position === 'fixed' ||
elementComputedStyle.position === 'relative' || elementComputedStyle.position === 'sticky' ||
elementComputedStyle.position === 'static') {
let siblingElement = element.nextElementSibling;
while (siblingElement) {
if (siblingElement.getBoundingClientRect().top > boundingRect.bottom || siblingElement.getBoundingClientRect().left > boundingRect.right) {
break;
}
if (siblingElement.getBoundingClientRect().bottom > boundingRect.top && siblingElement.getBoundingClientRect().right > boundingRect.left) {
obscured = true;
break;
}
siblingElement = siblingElement.nextElementSibling;
}
if (obscured) return false;
}
// If all checks have passed, the element is visible
return true;
}
来自http://code.jquery.com/jquery-1.11.1.js的jQuery代码有一个isHidden参数
var isHidden = function( elem, el ) {
// isHidden might be called from jQuery#filter function;
// in that case, element will be second argument
elem = el || elem;
return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
};
因此,看起来有一个与所有者文档相关的额外检查
我想知道这是否真的适用于以下情况:
基于zIndex隐藏在其他元素后面的元素 完全透明的元素使它们不可见 位于屏幕外的元素(即左:-1000px) 具有可见性的元素:隐藏 有显示的元素:无 没有可见文本或子元素的元素 高度或宽度设置为0的元素
这就是我所做的:
HTML和CSS:默认情况下使元素隐藏
<html>
<body>
<button onclick="myFunction()">Click Me</button>
<p id="demo" style ="visibility: hidden;">Hello World</p>
</body>
</html>
JavaScript:增加了一个代码来检查可见性是否被隐藏:
<script>
function myFunction() {
if ( document.getElementById("demo").style.visibility === "hidden"){
document.getElementById("demo").style.visibility = "visible";
}
else document.getElementById("demo").style.visibility = "hidden";
}
</script>
下面是我编写的代码,用于在几个类似的元素中找到唯一可见的元素,并返回其“class”属性的值,而不使用jQuery:
// Build a NodeList:
var nl = document.querySelectorAll('.myCssSelector');
// convert it to array:
var myArray = [];for(var i = nl.length; i--; myArray.unshift(nl[i]));
// now find the visible (= with offsetWidth more than 0) item:
for (i =0; i < myArray.length; i++){
var curEl = myArray[i];
if (curEl.offsetWidth !== 0){
return curEl.getAttribute("class");
}
}
Chrome 105(以及Edge和Opera)和Firefox 106引入了element . checkvisibility(),如果元素是可见的,则返回true,否则返回false。
该函数检查了使元素不可见的各种因素,包括display:none、可见性、内容可见性和不透明度:
let element = document.getElementById("myIcon");
let isVisible = element.checkVisibility({
checkOpacity: true, // Check CSS opacity property too
checkVisibilityCSS: true // Check CSS visibility property too
});
旁注:checkVisibility()以前被称为isVisible()。看这个GitHub问题。 参见这里的checkVisibility()规范草案。