Implementierung von Feature-Erkennung
Die Feature-Erkennung beinhaltet, herauszufinden, ob ein Browser einen bestimmten Codeblock unterstützt, und führt je nach Ergebnis unterschiedlichen Code aus, sodass der Browser immer eine funktionierende Erfahrung bieten kann, anstatt in einigen Browsern abzustürzen oder Fehlermeldungen zu erzeugen. Dieser Artikel erläutert, wie Sie Ihre eigene einfache Feature-Erkennung schreiben, wie Sie eine Bibliothek zur Beschleunigung der Implementierung verwenden und die nativen Funktionen zur Feature-Erkennung wie @supports
.
Voraussetzungen: | Vertrautheit mit den Kernsprachen HTML, CSS und JavaScript; eine Vorstellung von den grundlegenden Prinzipien des Cross-Browser-Tests. |
---|---|
Ziel: | Zu verstehen, was das Konzept der Feature-Erkennung ist, und in der Lage zu sein, geeignete Lösungen in CSS und JavaScript zu implementieren. |
Das Konzept der Feature-Erkennung
Die Idee hinter der Feature-Erkennung ist, dass Sie einen Test durchführen können, um zu bestimmen, ob ein Feature im aktuellen Browser unterstützt wird, und dann bedingt Code ausführen, um sowohl in Browsern, die das Feature unterstützen, als auch in Browsern, die es nicht unterstützen, eine akzeptable Erfahrung zu bieten. Wenn Sie dies nicht tun, könnte es passieren, dass Browser, die die von Ihnen verwendeten Features nicht unterstützen, Ihre Seiten nicht richtig anzeigen oder komplett ausfallen, was eine schlechte Benutzererfahrung schafft.
Lassen Sie uns rekapitulieren und uns das Beispiel ansehen, das wir in unserem Umgang mit häufigen JavaScript-Problemen behandelt haben — die Geolocation API (die die Standortdaten des Geräts, auf dem der Webbrowser läuft, zugänglich macht), hat den Haupteinstiegspunkt für ihre Nutzung, eine geolocation
-Eigenschaft, die im globalen Navigator-Objekt verfügbar ist. Daher können Sie feststellen, ob der Browser Geolocation unterstützt oder nicht, indem Sie etwas wie das Folgende verwenden:
if ("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition(function (position) {
// show the location on a map, such as the Google Maps API
});
} else {
// Give the user a choice of static maps
}
Bevor wir weitermachen, möchten wir eine Sache vorweg sagen — verwechseln Sie die Feature-Erkennung nicht mit Browser-Sniffing (Erkennung, welcher spezifische Browser auf die Seite zugreift) — dies ist eine schreckliche Praxis, die unter allen Umständen vermieden werden sollte. Siehe don't browser sniff für mehr Details.
Eigene Feature-Erkennungstests schreiben
In diesem Abschnitt werden wir uns ansehen, wie Sie Ihre eigenen Feature-Erkennungstests sowohl in CSS als auch in JavaScript implementieren können.
CSS
Sie können Tests für CSS-Features schreiben, indem Sie in JavaScript die Existenz von element.style.property (z.B. paragraph.style.rotate
) testen.
Ein klassisches Beispiel könnte sein, die Unterstützung von Subgrid in einem Browser zu testen; für Browser, die den subgrid
-Wert für einen Subgrid-Wert für grid-template-columns
und grid-template-rows
unterstützen, können wir Subgrid in unserem Layout verwenden. Für Browser, die dies nicht tun, könnten wir ein reguläres Raster verwenden, das gut funktioniert, aber nicht so cool aussieht.
Als Beispiel könnten wir ein Subgrid-Stylesheet einfügen, wenn der Wert unterstützt wird, und ein reguläres Grid-Stylesheet, wenn nicht. Dazu könnten wir zwei Stylesheets im Kopf unserer HTML-Datei einbinden: eines für das gesamte Styling und eines, das das Standard-Layout implementiert, wenn Subgrid nicht unterstützt wird:
<link href="basic-styling.css" rel="stylesheet" />
<link class="conditional" href="grid-layout.css" rel="stylesheet" />
Hier behandelt basic-styling.css
das gesamte Styling, das wir jedem Browser geben möchten. Wir haben zwei zusätzliche CSS-Dateien, grid-layout.css
und subgrid-layout.css
, die das CSS enthalten, das wir abhängig von den Unterstützungsstufen selektiv auf Browser anwenden wollen.
Wir verwenden JavaScript, um die Unterstützung für den Subgrid-Wert zu testen, und aktualisieren dann das href
unseres konditionellen Stylesheets basierend auf der Unterstützung im Browser.
Wir können ein <script></script>
in unser Dokument einfügen, gefüllt mit dem folgenden JavaScript:
const conditional = document.querySelector(".conditional");
if (CSS.supports("grid-template-columns", "subgrid")) {
conditional.setAttribute("href", "subgrid-layout.css");
}
In unserer bedingten Anweisung testen wir, ob die grid-template-columns
-Eigenschaft den subgrid
-Wert mithilfe von CSS.supports()
unterstützt.
@supports
CSS hat einen nativen Mechanismus zur Feature-Erkennung: die @supports
-Regel. Diese funktioniert ähnlich wie Media-Queries, außer dass sie nicht selektiv CSS je nach einer Media-Eigenschaft wie Auflösung, Bildschirmbreite oder Seitenverhältnis anwendet, sondern selektiv CSS abhängig davon anwendet, ob ein CSS-Feature unterstützt wird, ähnlich wie CSS.supports()
.
Zum Beispiel könnten wir unser vorheriges Beispiel umschreiben, um @supports
zu verwenden:
@supports (grid-template-columns: subgrid) {
main {
display: grid;
grid-template-columns: repeat(9, 1fr);
grid-template-rows: repeat(4, minmax(100px, auto));
}
.item {
display: grid;
grid-column: 2 / 7;
grid-row: 2 / 4;
grid-template-columns: subgrid;
grid-template-rows: repeat(3, 80px);
}
.subitem {
grid-column: 3 / 6;
grid-row: 1 / 3;
}
}
Dieser Regelblock wendet die CSS-Regel nur dann an, wenn der aktuelle Browser die grid-template-columns: subgrid;
-Deklaration unterstützt. Damit eine Bedingung mit einem Wert funktioniert, müssen Sie eine vollständige Deklaration (nicht nur einen Eigenschaftsnamen) einfügen und am Ende KEIN Semikolon hinzufügen.
@supports
bietet auch AND
, OR
und NOT
-Logik — der andere Block wendet das reguläre Grid-Layout an, wenn die Subgrid-Option nicht verfügbar ist:
@supports not (grid-template-columns: subgrid) {
/* rules in here */
}
Dies ist bequemer als das vorherige Beispiel — wir können unsere gesamte Feature-Erkennung in CSS durchführen, kein JavaScript erforderlich, und wir können die gesamte Logik in einer einzigen CSS-Datei behandeln, was die Anzahl der HTTP-Anfragen reduziert. Aus diesem Grund ist dies die bevorzugte Methode, um die Unterstützung für CSS-Features im Browser zu bestimmen.
JavaScript
Wir haben zuvor ein Beispiel für einen JavaScript-Feature-Erkennungstest gesehen. Im Allgemeinen werden solche Tests nach einem der wenigen gängigen Muster durchgeführt.
Gängige Muster für erkennbare Features umfassen:
- Mitglieder eines Objekts
-
Prüfen Sie, ob eine bestimmte Methode oder Eigenschaft (typischerweise ein Einstiegspunkt zur Nutzung der API oder eines anderen Features, das Sie erkennen möchten) in ihrem übergeordneten
Object
existiert.Unser früheres Beispiel verwendete dieses Muster, um die Unterstützung der Geolocation zu erkennen, indem das
navigator
-Objekt auf eingeolocation
-Mitglied getestet wurde:jsif ("geolocation" in navigator) { // Access navigator.geolocation APIs }
- Eigenschaften eines Elements
-
Erstellen Sie ein Element im Speicher mit
Document.createElement()
und prüfen Sie, ob eine Eigenschaft darauf existiert.Dieses Beispiel zeigt eine Möglichkeit, die Unterstützung der Canvas API zu erkennen:
jsfunction supports_canvas() { return !!document.createElement("canvas").getContext; } if (supports_canvas()) { // Create and draw on canvas elements }
- Spezifische Rückgabewerte einer Methode auf einem Element
-
Erstellen Sie ein Element im Speicher mit
Document.createElement()
und prüfen Sie, ob eine Methode darauf existiert. Wenn ja, prüfen Sie, welchen Wert sie zurückgibt. - Beibehaltung eines zugewiesenen Eigenschaftswerts durch ein Element
-
Erstellen Sie ein Element im Speicher mit
Document.createElement()
, setzen Sie eine Eigenschaft auf einen bestimmten Wert, und prüfen Sie dann, ob der Wert beibehalten wird.
Bedenken Sie, dass jedoch einige Features als nicht erkennbar bekannt sind. In diesen Fällen müssen Sie einen anderen Ansatz verwenden, wie z.B. die Verwendung eines Polyfills.
matchMedia
Wir wollten an dieser Stelle auch die JavaScript-Funktion Window.matchMedia
erwähnen. Dies ist eine Eigenschaft, die es Ihnen erlaubt, Media-Query-Tests innerhalb von JavaScript durchzuführen. Es sieht so aus:
if (window.matchMedia("(max-width: 480px)").matches) {
// run JavaScript in here.
}
Ein Beispiel: Unser Snapshot Demo nutzt dies, um selektiv die Brick JavaScript-Bibliothek anzuwenden und sie für das UI-Layout zu verwenden, aber nur für das Layout des kleinen Bildschirms (480px breit oder weniger). Zuerst verwenden wir das media
Attribut, um das Brick CSS nur auf die Seite anzuwenden, wenn die Seitenbreite 480px oder weniger beträgt:
<link
href="dist/brick.css"
rel="stylesheet"
media="all and (max-width: 480px)" />
Dann verwenden wir matchMedia()
mehrmals im JavaScript, um die Brick-Navigationsfunktionen nur dann auszuführen, wenn wir uns im kleinen Bildschirm-Layout befinden (in breiteren Bildschirm-Layouts kann alles auf einmal gesehen werden, sodass wir nicht zwischen verschiedenen Ansichten navigieren müssen).
if (window.matchMedia("(max-width: 480px)").matches) {
deck.shuffleTo(1);
}