Controleer of element zichtbaar is in DOM

Is er een manier waarop ik kan controleren of een element zichtbaar is in pure JS (geen jQuery) ?

Dus, bijvoorbeeld, in deze pagina: Performance Bikes, als je met de muis over Deals gaat (in het top menu), verschijnt er een venster met deals, maar in het begin werd het niet getoond. Het staat wel in de HTML, maar het is niet zichtbaar.

Dus, gegeven een DOM element, hoe kan ik controleren of het zichtbaar is of niet? Ik heb het geprobeerd:

window.getComputedStyle(my_element)['display']);

maar het lijkt niet te werken. Ik vraag me af welke attributen ik moet controleren. Het schiet me zo te binnen:

display !== 'none'
visibility !== 'hidden'

Zijn er nog andere die ik misschien mis?

Oplossing

Volgens deze MDN documentatie zal een element's offsetParent eigenschap null teruggeven wanneer het, of een van zijn ouders, verborgen is via de display style eigenschap. Zorg er alleen voor dat het element'niet gefixeerd is. Een script om dit te controleren, als je geen position: fixed; elementen op je pagina hebt, zou er als volgt uit kunnen zien:

// Where el is the DOM element you'd like to test for visibility
function isHidden(el) {
    return (el.offsetParent === null)
}

Aan de andere kant, als je wel elementen met een vaste positie hebt die in deze zoekactie terecht zouden kunnen komen, zul je helaas (en langzaam) window.getComputedStyle() moeten gebruiken. De functie in dat geval zou kunnen zijn:

// Where el is the DOM element you'd like to test for visibility
function isHidden(el) {
    var style = window.getComputedStyle(el);
    return (style.display === 'none')
}

Optie #2 is waarschijnlijk iets eenvoudiger omdat het rekening houdt met meer randgevallen, maar ik durf te wedden dat het ook een stuk trager is, dus als je deze operatie vele malen moet herhalen, kun je deze beter vermijden.

Commentaren (19)

Dit kan helpen : Verberg het element door het op de meest linkse positie te zetten en controleer dan de offsetLeft eigenschap. Als je jQuery wilt gebruiken kun je gewoon de :visible selector controleren en de zichtbaarheidsstatus van het element krijgen.

HTML :

<div id="myDiv">Hello</div>

CSS :


#myDiv{
   position:absolute;
   left : -2000px;
}


#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 hidden!!");        
}

jsFiddle

Commentaren (7)

Als we toch bezig zijn met het verzamelen van basis manieren om zichtbaarheid te detecteren:

opacity > 0.01; // probably more like .1 to actually be visible, but YMMV

En wat betreft de manier om attributen te verkrijgen:

element.getAttribute(attributename);

Dus, in jouw voorbeeld:

document.getElementById('snDealsPanel').getAttribute('visibility');

Maar wat? Het werkt hier niet. Kijk beter en je'll vindt dat zichtbaarheid niet wordt bijgewerkt als een attribuut op het element, maar met behulp van de style eigenschap. Dit is een van de vele problemen bij het proberen te doen wat jij'doet. Onder andere: je kunt niet garanderen dat er werkelijk iets te zien is in een element, alleen omdat zijn visibility, display, en opacity allemaal de juiste waarden hebben. Het zou nog steeds inhoud kunnen missen, of het zou een hoogte en breedte kunnen missen. Een ander object kan het verduisteren. Voor meer details, een snelle Google zoektocht onthult dit, en bevat zelfs een bibliotheek om het probleem op te lossen. (YMMV)

Kijk ook eens naar de volgende, die mogelijk duplicaten zijn van deze vraag, met uitstekende antwoorden, inclusief enig inzicht van de machtige John Resig. Uw specifieke use-case is echter iets anders dan de standaard, dus ik'zal afzien van het markeren:

(EDIT: OP ZEGT DAT HIJ'S PAGINA'S SCHRAAPT, NIET MAAKT, DUS ONDERSTAANDE IS'NIET VAN TOEPASSING) Een betere optie? Bind de zichtbaarheid van elementen aan modeleigenschappen en laat de zichtbaarheid altijd afhangen van dat model, zoals Angular doet met ng-show. Je kunt dat doen met elk gereedschap dat je wilt: Angular, gewone JS, wat dan ook. Beter nog, je kunt de DOM-implementatie in de loop van de tijd veranderen, maar je'zult altijd in staat zijn om de toestand uit het model te lezen, in plaats van uit het DOM. Je waarheid uit het DOM lezen is slecht. En traag. Veel beter is het om het model te controleren, en te vertrouwen op je implementatie om ervoor te zorgen dat de DOM-status het model weerspiegelt. (En gebruik geautomatiseerde testen om die aanname te bevestigen).

Commentaren (1)