有什么方法,我可以检查如果一个元素是可见的纯JS(没有jQuery) ?
因此,给定一个DOM元素,我如何检查它是否可见?我试着:
window.getComputedStyle(my_element)['display']);
但这似乎并不奏效。我想知道我应该检查哪些属性。我想到了:
display !== 'none'
visibility !== 'hidden'
还有我可能漏掉的吗?
有什么方法,我可以检查如果一个元素是可见的纯JS(没有jQuery) ?
因此,给定一个DOM元素,我如何检查它是否可见?我试着:
window.getComputedStyle(my_element)['display']);
但这似乎并不奏效。我想知道我应该检查哪些属性。我想到了:
display !== 'none'
visibility !== 'hidden'
还有我可能漏掉的吗?
当前回答
下面是一个(纯纯的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;
}
其他回答
下面是一个(纯纯的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;
}
var visible = document.getElementById("yourelementID's");
if (visible){
// make events
} else
{
//other events
}
这可能会有帮助: 将元素隐藏在最左边的位置,然后检查offsetLeft属性。如果你想使用jQuery,你可以简单地检查:visible选择器并获得元素的可见状态。
HTML:
<div id="myDiv">Hello</div>
CSS:
<!-- for javaScript-->
#myDiv{
position:absolute;
left : -2000px;
}
<!-- for jQuery -->
#myDiv{
visibility:hidden;
}
javaScript:
var myStyle = document.getElementById("myDiv").offsetLeft;
if(myStyle < 0){
alert("Div is hidden!!");
}
jQuery:
if( $("#MyElement").is(":visible") == true )
{
alert("Div is visible!!");
}
js小提琴
如果我们只是收集检测能见度的基本方法,让我不要忘记:
opacity > 0.01; // probably more like .1 to actually be visible, but YMMV
至于如何获取属性:
element.getAttribute(attributename);
所以,在你的例子中:
document.getElementById('snDealsPanel').getAttribute('visibility');
But wha? It doesn't work here. Look closer and you'll find that visibility is being updated not as an attribute on the element, but using the style property. This is one of many problems with trying to do what you're doing. Among others: you can't guarantee that there's actually something to see in an element, just because its visibility, display, and opacity all have the correct values. It still might lack content, or it might lack a height and width. Another object might obscure it. For more detail, a quick Google search reveals this, and even includes a library to try solving the problem. (YMMV)
看看下面的问题,它们可能是这个问题的副本,有很好的答案,包括来自强大的约翰·雷西格的一些见解。但是,您的特定用例与标准用例略有不同,因此我将避免标记:
如何判断一个DOM元素是否在当前视口中可见? 如何检查一个元素是否真的可见javascript?
(EDIT: OP SAYS HE'S SCRAPING PAGES, NOT CREATING THEM, SO BELOW ISN'T APPLICABLE) A better option? Bind the visibility of elements to model properties and always make visibility contingent on that model, much as Angular does with ng-show. You can do that using any tool you want: Angular, plain JS, whatever. Better still, you can change the DOM implementation over time, but you'll always be able to read state from the model, instead of the DOM. Reading your truth from the DOM is Bad. And slow. Much better to check the model, and trust in your implementation to ensure that the DOM state reflects the model. (And use automated testing to confirm that assumption.)
let element = document.getElementById('element');
let rect = element.getBoundingClientRect();
if(rect.top == 0 &&
rect.bottom == 0 &&
rect.left == 0 &&
rect.right == 0 &&
rect.width == 0 &&
rect.height == 0 &&
rect.x == 0 &&
rect.y == 0)
{
alert('hidden');
}
else
{
alert('visible');
}