Ελέγξτε αν το στοιχείο είναι ορατό στο DOM

Υπάρχει κάποιος τρόπος να ελέγξω αν ένα στοιχείο είναι ορατό σε καθαρό JS (χωρίς jQuery);

Έτσι, για παράδειγμα, σε αυτή τη σελίδα: Performance Bikes, αν περάσετε με το ποντίκι πάνω από το Deals (στο επάνω μενού), εμφανίζεται ένα παράθυρο με τις προσφορές, αλλά στην αρχή δεν εμφανιζόταν. Υπάρχει στην HTML, αλλά δεν είναι ορατό.

Έτσι, δεδομένου ενός στοιχείου DOM, πώς μπορώ να ελέγξω αν είναι ορατό ή όχι; Δοκίμασα:

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

αλλά δεν φαίνεται να λειτουργεί. Αναρωτιέμαι ποια χαρακτηριστικά πρέπει να ελέγξω. Μου έρχεται στο μυαλό:

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

Υπάρχουν άλλα που μπορεί να μου λείπουν;

Λύση

Σύμφωνα με αυτή την τεκμηρίωση του MDN, η ιδιότητα offsetParent ενός στοιχείου θα επιστρέφει null κάθε φορά που αυτό, ή οποιοσδήποτε από τους γονείς του, είναι κρυμμένος μέσω της ιδιότητας display style. Απλά βεβαιωθείτε ότι το στοιχείο δεν είναι σταθερό. Ένα σενάριο για να το ελέγξετε αυτό, αν δεν έχετε στοιχεία position: fixed; στη σελίδα σας, θα μπορούσε να μοιάζει ως εξής:

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

Από την άλλη πλευρά, αν έχετε στοιχεία σταθερής θέσης που μπορεί να πιαστούν σε αυτή την αναζήτηση, θα πρέπει δυστυχώς (και αργά) να χρησιμοποιήσετε το `window.getComputedStyle(). Η συνάρτηση σε αυτή την περίπτωση μπορεί να είναι η εξής:

// 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')
}

Η επιλογή #2 είναι πιθανώς λίγο πιο απλή, αφού λαμβάνει υπόψη της περισσότερες ακραίες περιπτώσεις, αλλά στοιχηματίζω ότι είναι και πολύ πιο αργή, οπότε αν πρέπει να επαναλάβετε αυτή τη λειτουργία πολλές φορές, καλύτερα μάλλον να την αποφύγετε.

Σχόλια (19)

Αυτό μπορεί να βοηθήσει : Κρύψτε το στοιχείο τοποθετώντας το στην πιο αριστερή θέση και στη συνέχεια ελέγξτε την ιδιότητα offsetLeft. Αν θέλετε να χρησιμοποιήσετε το jQuery μπορείτε απλά να ελέγξετε τον επιλογέα :visible και να λάβετε την κατάσταση ορατότητας του στοιχείου.

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

Σχόλια (7)

Αν συλλέγουμε μόνο βασικούς τρόπους ανίχνευσης της ορατότητας, ας μην ξεχνάμε:

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

Και όσον αφορά τον τρόπο απόκτησης των χαρακτηριστικών:

element.getAttribute(attributename);

Έτσι, στο παράδειγμά σας:

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

Αλλά τι; Δεν λειτουργεί εδώ. Κοιτάξτε πιο προσεκτικά και θα διαπιστώσετε ότι η ορατότητα ενημερώνεται όχι ως ιδιότητα στο στοιχείο, αλλά χρησιμοποιώντας την ιδιότητα style. Αυτό είναι ένα από τα πολλά προβλήματα με την προσπάθεια να κάνετε αυτό που κάνετε. Μεταξύ άλλων: δεν μπορείτε να εγγυηθείτε ότι υπάρχει πραγματικά κάτι να δείτε σε ένα στοιχείο, μόνο και μόνο επειδή η ορατότητα, η εμφάνιση και η αδιαφάνεια του έχουν όλες τις σωστές τιμές. Μπορεί ακόμα να μην έχει περιεχόμενο ή να μην έχει ύψος και πλάτος. Ένα άλλο αντικείμενο μπορεί να το επισκιάζει. Για περισσότερες λεπτομέρειες, μια γρήγορη αναζήτηση στο Google αποκαλύπτει αυτό, και περιλαμβάνει ακόμη και μια βιβλιοθήκη για να προσπαθήσετε να λύσετε το πρόβλημα. (YMMV)

Ελέγξτε τα παρακάτω, τα οποία είναι πιθανά αντίγραφα αυτής της ερώτησης, με εξαιρετικές απαντήσεις, συμπεριλαμβανομένης και κάποιας διορατικότητας από τον πανίσχυρο John Resig. Ωστόσο, η δική σας συγκεκριμένη περίπτωση χρήσης είναι ελαφρώς διαφορετική από την τυπική, οπότε θα αποφύγω να την επισημάνω:

(ΕΠΕΞΕΡΓΑΣΊΑ: Ο OP ΛΈΕΙ ΌΤΙ ΣΑΡΏΝΕΙ ΣΕΛΊΔΕΣ, ΔΕΝ ΤΙΣ ΔΗΜΙΟΥΡΓΕΊ, ΟΠΌΤΕ ΤΟ ΠΑΡΑΚΆΤΩ ΔΕΝ ΙΣΧΎΕΙ) Μια καλύτερη επιλογή; Δέστε την ορατότητα των στοιχείων σε ιδιότητες του μοντέλου και εξαρτήστε πάντα την ορατότητα από αυτό το μοντέλο, όπως κάνει η Angular με το ng-show. Μπορείτε να το κάνετε αυτό χρησιμοποιώντας οποιοδήποτε εργαλείο θέλετε: Angular, απλό JS, οτιδήποτε. Ακόμα καλύτερα, μπορείτε να αλλάξετε την υλοποίηση του DOM με την πάροδο του χρόνου, αλλά θα μπορείτε πάντα να διαβάζετε την κατάσταση από το μοντέλο, αντί για το DOM. Το να διαβάζετε την αλήθεια σας από το DOM είναι κακό. Και αργό. Πολύ καλύτερα να ελέγχετε το μοντέλο και να εμπιστεύεστε την υλοποίησή σας για να διασφαλίσετε ότι η κατάσταση του DOM αντικατοπτρίζει το μοντέλο. (Και χρησιμοποιήστε αυτοματοποιημένες δοκιμές για να επιβεβαιώσετε αυτή την υπόθεση).

Σχόλια (1)