Τα αναγνωριστικά με όνομα στοιχείων μπορούν να αναφέρονται ως JavaScript Globals PlatoBlockchain Data Intelligence. Κάθετη αναζήτηση. Ολα συμπεριλαμβάνονται.

Τα αναγνωριστικά με όνομα στοιχείων μπορούν να αναφέρονται ως παγκόσμιες JavaScript

Γνωρίζατε ότι τα στοιχεία DOM με αναγνωριστικά είναι προσβάσιμα στο JavaScript ως καθολικές μεταβλητές; Είναι ένα από εκείνα τα πράγματα που υπάρχουν για πάντα, αλλά πραγματικά το σκάβω για πρώτη φορά.

Αν είναι η πρώτη φορά που το ακούτε, φροντίστε! Μπορούμε να το δούμε σε δράση απλά προσθέτοντας ένα αναγνωριστικό σε ένα στοιχείο σε HTML:

Κανονικά, θα ορίζαμε μια νέα μεταβλητή χρησιμοποιώντας querySelector("#cool") or getElementById("cool") για να επιλέξετε αυτό το στοιχείο:

var el = querySelector("#cool");

Αλλά στην πραγματικότητα έχουμε ήδη πρόσβαση #cool χωρίς αυτό το αστείο:

Έτσι, οποιαδήποτε id - ή name χαρακτηριστικό, για αυτό το θέμα — στο HTML μπορεί να προσπελαστεί σε JavaScript χρησιμοποιώντας window[ELEMENT_ID]. Και πάλι, αυτό δεν είναι ακριβώς "νέο", αλλά είναι πραγματικά ασυνήθιστο να το δούμε.

Όπως μπορείτε να μαντέψετε, η πρόσβαση στο παγκόσμιο εύρος με επώνυμες αναφορές δεν είναι η καλύτερη ιδέα. Μερικοί άνθρωποι έφτασαν να το αποκαλούν αυτό ως «ρυπαίνοντας την παγκόσμια εμβέλεια». Θα εξετάσουμε γιατί συμβαίνει αυτό, αλλά πρώτα…

Κάποιο πλαίσιο

Αυτή η προσέγγιση είναι περιγράφεται στις προδιαγραφές HTML, όπου περιγράφεται ως "ονομαστική πρόσβαση στο Window αντικείμενο."

Ο Internet Explorer ήταν ο πρώτος που εφάρμοσε τη δυνατότητα. Όλα τα άλλα προγράμματα περιήγησης το πρόσθεσαν επίσης. Το Gecko ήταν το μόνο πρόγραμμα περιήγησης εκείνη την εποχή που δεν το υποστήριζε απευθείας σε τυπική λειτουργία, επέλεξε να το κάνει πειραματικό χαρακτηριστικό. Υπήρχε δισταγμός να το εφαρμόσει καθόλου, αλλά αυτό προχώρησε στο όνομα της συμβατότητας του προγράμματος περιήγησης (Ο Γκέκο προσπάθησε μάλιστα πείσει το WebKit για να το μετακινήσετε από τη λειτουργία προτύπων) και τελικά το μεταφέρατε στη λειτουργία προτύπων στον Firefox 14.

Ένα πράγμα που μπορεί να μην είναι καλά γνωστό είναι ότι τα προγράμματα περιήγησης έπρεπε να λάβουν ορισμένα προληπτικά μέτρα - με διαφορετικούς βαθμούς επιτυχίας - για να διασφαλίσουν ότι τα παγκόσμια που δημιουργήθηκαν δεν θα σπάσουν την ιστοσελίδα. Ένα τέτοιο μέτρο είναι…

Μεταβλητή σκίαση

Πιθανώς το πιο ενδιαφέρον μέρος αυτής της δυνατότητας είναι ότι οι αναφορές ονομασμένων στοιχείων δεν το κάνουν σκιά υπάρχουσες καθολικές μεταβλητές. Έτσι, εάν ένα στοιχείο DOM έχει ένα id που έχει ήδη οριστεί ως παγκόσμιο, δεν θα παρακάμψει το υπάρχον. Για παράδειγμα:


  
    window.foo = "bar";
  


  
I won't override window.foo
console.log(window.foo); // Prints "bar"

Και ισχύει και το αντίθετο:

I will be overridden :(
window.foo = "bar"; console.log(window.foo); // Prints "bar"

Αυτή η συμπεριφορά είναι απαραίτητη γιατί ακυρώνει επικίνδυνες παρακάμψεις όπως π.χ

, που διαφορετικά θα δημιουργούσε σύγκρουση ακυρώνοντας το alert API. Αυτή η τεχνική προστασίας μπορεί κάλλιστα να είναι ο λόγος που εσείς —αν είστε σαν εμένα— το μαθαίνετε για πρώτη φορά.

Η υπόθεση εναντίον επώνυμων παγκόσμιων

Νωρίτερα, είπα ότι η χρήση παγκόσμιων στοιχείων με όνομα ως αναφορές μπορεί να μην είναι η καλύτερη ιδέα. Υπάρχουν πολλοί λόγοι για αυτό, οι οποίοι Ο TJ VanToll έχει καλύψει όμορφα στο blog του και θα συνοψίσω εδώ:

  • Εάν αλλάξει το DOM, αλλάζει και η αναφορά. Αυτό κάνει μερικά πραγματικά «εύθραυστα» (ο όρος της προδιαγραφής για αυτό) κώδικα όπου ο διαχωρισμός των ανησυχιών μεταξύ HTML και JavaScript μπορεί να είναι υπερβολικός.
  • Οι τυχαίες αναφορές είναι πολύ εύκολες. Ένα απλό τυπογραφικό λάθος μπορεί κάλλιστα να καταλήξει με αναφορά σε ένα επώνυμο παγκόσμιο και να σας δώσει απροσδόκητα αποτελέσματα.
  • Εφαρμόζεται διαφορετικά στα προγράμματα περιήγησης. Για παράδειγμα, θα πρέπει να έχουμε πρόσβαση σε μια άγκυρα με ένα id - π.χ — αλλά ορισμένα προγράμματα περιήγησης (συγκεκριμένα το Safari και το Firefox) επιστρέφουν α ReferenceError στην κονσόλα.
  • Μπορεί να μην επιστρέψει αυτό που νομίζετε. Σύμφωνα με την προδιαγραφή, όταν υπάρχουν πολλαπλές παρουσίες του ίδιου ονομασμένου στοιχείου στο DOM — ας πούμε, δύο περιπτώσεις

    — το πρόγραμμα περιήγησης θα πρέπει να επιστρέψει ένα HTMLCollection με μια σειρά από στιγμιότυπα. Ο Firefox, ωστόσο, επιστρέφει μόνο την πρώτη περίπτωση. Μετά πάλι, λέει η προδιαγραφή θα πρέπει να χρησιμοποιήσουμε ένα παράδειγμα ενός id στο δέντρο ενός στοιχείου ούτως ή άλλως. Αλλά κάτι τέτοιο δεν θα εμποδίσει μια σελίδα να λειτουργεί ή κάτι τέτοιο.

  • Ίσως υπάρχει κόστος απόδοσης; Θέλω να πω, το πρόγραμμα περιήγησης πρέπει να κάνει αυτή τη λίστα αναφορών και να τη διατηρεί. Κάποιοι άνθρωποι έκαναν δοκιμές σε αυτό το νήμα StackOverflow, όπου στην πραγματικότητα βρίσκονταν οι επώνυμοι παγκόσμιοι μεγαλύτερη απόδοση σε μία δοκιμή και λιγότερο επιδόσεις σε μια πιο πρόσφατη δοκιμή.

Πρόσθετες εκτιμήσεις

Ας υποθέσουμε ότι αποκλείουμε τις επικρίσεις κατά της χρήσης επώνυμων παγκόσμιων και τις χρησιμοποιούμε ούτως ή άλλως. Είναι όλα καλά. Αλλά υπάρχουν μερικά πράγματα που μπορεί να θέλετε να εξετάσετε όπως κάνετε.

Πολυπληρώματα

Όσο και αν ακούγεται ασήμαντο, αυτοί οι τύποι καθολικών ελέγχων είναι μια τυπική απαίτηση εγκατάστασης για πολυγεμίσεις. Δείτε το παρακάτω παράδειγμα όπου ορίσαμε ένα cookie χρησιμοποιώντας το νέο CookieStore API, πολυσυμπλήρωσή του σε προγράμματα περιήγησης που δεν το υποστηρίζουν ακόμα:


  
  
    // Polyfill the CookieStore API if not yet implemented.
    // https://developer.mozilla.org/en-US/docs/Web/API/CookieStore
    if (!window.cookieStore) {
      window.cookieStore = myCookieStorePolyfill;
    }
    cookieStore.set("foo", "bar");
  

Αυτός ο κώδικας λειτουργεί τέλεια στο Chrome, αλλά εκπέμπει το ακόλουθο σφάλμα στο Safari.:

TypeError: cookieStore.set is not a function

Το Safari δεν έχει υποστήριξη για το CookieStore API από τη σύνταξη αυτού του άρθρου. Ως αποτέλεσμα, το πολυγέμισμα δεν εφαρμόζεται επειδή το img Το αναγνωριστικό στοιχείου δημιουργεί μια καθολική μεταβλητή που έρχεται σε σύγκρουση με το cookieStore παγκόσμια

Ενημερώσεις JavaScript API

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

Για παράδειγμα:


  
  
    window.BarcodeDetector.focus();
  

Αυτό το σενάριο παίρνει μια αναφορά στο στοιχείο εισόδου και καλεί focus() πάνω του. Λειτουργεί σωστά. Ωστόσο, δεν ξέρουμε πώς μακρύς θα συνεχίσει να λειτουργεί.

Βλέπετε, η καθολική μεταβλητή που χρησιμοποιούμε για την αναφορά στο στοιχείο εισόδου θα σταματήσει να λειτουργεί μόλις τα προγράμματα περιήγησης αρχίσουν να υποστηρίζουν BarcodeDetector API. Σε εκείνο το σημείο, το window.BarcodeDetector καθολική δεν θα είναι πλέον αναφορά στο στοιχείο εισόδου και .focus() θα ρίξει ένα "window.BarcodeDetector.focus δεν είναι σφάλμα συνάρτησης.

Μπόνους: Δεν δημιουργούν όλα τα κατονομαζόμενα στοιχεία καθολικές αναφορές

Θέλετε να ακούσετε κάτι αστείο; Για να προσθέσετε προσβολή στον τραυματισμό, τα στοιχεία με όνομα είναι προσβάσιμα ως καθολικές μεταβλητές μόνο εάν τα ονόματα δεν περιέχουν τίποτα άλλο εκτός από γράμμα. Τα προγράμματα περιήγησης δεν θα δημιουργήσουν μια καθολική αναφορά για ένα στοιχείο με αναγνωριστικό που περιέχει ειδικούς χαρακτήρες και αριθμούς, όπως π.χ hello-world και item1.

Συμπέρασμα

Ας συνοψίσουμε πώς φτάσαμε εδώ:

  • Όλα τα μεγάλα προγράμματα περιήγησης δημιουργούν αυτόματα καθολικές αναφορές σε κάθε στοιχείο DOM με ένα id (ή, σε ορισμένες περιπτώσεις, α name Χαρακτηριστικό).
  • Η πρόσβαση σε αυτά τα στοιχεία μέσω των παγκόσμιων αναφορών τους είναι αναξιόπιστη και δυνητικά επικίνδυνη. Χρήση querySelector or getElementById Αντιθέτως.
  • Εφόσον οι καθολικές αναφορές δημιουργούνται αυτόματα, ενδέχεται να έχουν κάποιες παρενέργειες στον κώδικά σας. Αυτός είναι ένας καλός λόγος για να αποφύγετε τη χρήση του id χαρακτηριστικό εκτός και αν το χρειάζεστε πραγματικά.

Στο τέλος της ημέρας, ίσως είναι καλή ιδέα να αποφύγετε τη χρήση επώνυμων παγκόσμιων στο JavaScript. Παρέθεσα την προδιαγραφή νωρίτερα σχετικά με τον τρόπο με τον οποίο οδηγεί σε "εύθραυστο" κώδικα, αλλά εδώ είναι το πλήρες κείμενο για να οδηγήσετε το σημείο στο σπίτι:

Κατά γενικό κανόνα, η βάση σε αυτό θα οδηγήσει σε εύθραυστο κώδικα. Ποια αναγνωριστικά καταλήγουν να αντιστοιχίζονται σε αυτό το API μπορεί να διαφέρουν με την πάροδο του χρόνου, καθώς για παράδειγμα προστίθενται νέες δυνατότητες στην πλατφόρμα ιστού. Αντί για αυτό, χρησιμοποιήστε document.getElementById() or document.querySelector().

Νομίζω ότι το γεγονός ότι η ίδια η προδιαγραφή HTML συνιστά να μείνετε μακριά από αυτό το χαρακτηριστικό μιλάει από μόνο του.

Σφραγίδα ώρας:

Περισσότερα από Κόλπα CSS