Implementierung von Feature-Erkennung
Feature-Erkennung beinhaltet das Feststellen, ob ein Browser einen bestimmten Codeblock unterstützt, und das Ausführen eines unterschiedlichen Codes, je nachdem, ob er dies tut (oder nicht), sodass der Browser immer ein funktionierendes Erlebnis bieten kann, anstatt in einigen Browsern abzustürzen oder Fehler zu verursachen. Dieser Artikel beschreibt, wie Sie Ihre eigene einfache Feature-Erkennung schreiben, wie Sie eine Bibliothek verwenden, um die Implementierung zu beschleunigen, und native Funktionen für die Feature-Erkennung wie @supports
.
Voraussetzungen: | Vertrautheit mit den grundlegenden HTML, CSS und JavaScript Sprachen; eine Vorstellung von den übergeordneten Prinzipien des Cross-Browser-Testings. |
---|---|
Zielsetzung: | 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 festzustellen, ob ein Feature im aktuellen Browser unterstützt wird, und dann Code bedingt ausführen, um ein akzeptables Erlebnis sowohl in Browsern zu bieten, die das Feature unterstützen, als auch in Browsern, die es nicht unterstützen. Wenn Sie dies nicht tun, könnten Browser, die die von Ihnen verwendeten Features nicht unterstützen, Ihre Websites möglicherweise nicht richtig anzeigen oder ganz ausfallen, was zu einem schlechten Benutzererlebnis führt.
Lassen Sie uns rekapitulieren und das Beispiel betrachten, das wir in unserem Artikel Umgehen häufiger JavaScript-Probleme angeschnitten haben — die Geolocation API (die verfügbare Standortdaten für das Gerät bereitstellt, auf dem der Webbrowser läuft) hat den Haupteinstiegspunkt für ihre Verwendung, eine geolocation
-Eigenschaft, die im globalen Navigator-Objekt verfügbar ist. Daher können Sie feststellen, ob der Browser Geolokalisierung 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 fortfahren, möchten wir eine Sache im Voraus sagen — verwechseln Sie Feature-Erkennung nicht mit Browser-Sniffing (Erkennung, welcher spezifische Browser auf die Seite zugreift) — dies ist eine schlechte Praxis, die unter allen Umständen zu vermeiden ist. Siehe don't browser sniff für weitere Details.
Schreiben Ihrer eigenen Feature-Erkennungstests
In diesem Abschnitt schauen wir uns an, wie Sie Ihre eigenen Feature-Erkennungstests sowohl in CSS als auch in JavaScript implementieren.
CSS
Sie können Tests für CSS-Features schreiben, indem Sie die Existenz von element.style.property (z.B. paragraph.style.rotate
) in JavaScript testen.
Ein klassisches Beispiel könnte sein, die Unterstützung für 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 Grid verwenden, das gut funktioniert, aber nicht so cool aussieht.
Anhand dieses Beispiels könnten wir ein Subgrid-Stylesheet einbinden, wenn der Wert unterstützt wird, und ein reguläres Grid-Stylesheet, wenn nicht. Dazu könnten wir zwei Stylesheets im Kopf unseres HTML-Dokuments einfügen: eines für die gesamte Gestaltung und eines, das das Standardlayout implementiert, wenn Subgrid nicht unterstützt wird:
<link href="basic-styling.css" rel="stylesheet" />
<link class="conditional" href="grid-layout.css" rel="stylesheet" />
Hierbei kümmert sich basic-styling.css
um alle Stilgestaltungen, die 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 selektiv auf Browser abhängig von ihren Unterstützungsniveaus anwenden möchten.
Wir verwenden JavaScript, um die Unterstützung für den Subgrid-Wert zu testen, und aktualisieren dann das href
unseres bedingten Stylesheets basierend auf der Browser-Unterstützung.
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 Bedingung 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
-At-Regel. Diese funktioniert auf ähnliche Weise wie Media Queries, außer dass statt selektivem Anwenden von CSS je nach Medienfeature wie Auflösung, Bildschirmbreite oder Seitenverhältnis, CSS je nach Unterstützung eines CSS-Features selektiv angewendet wird, ähnlich wie bei 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 At-Regelblock wendet die CSS-Regel nur dann an, wenn der aktuelle Browser die grid-template-columns: subgrid;
-Deklaration unterstützt. Für eine Bedingung mit einem Wert müssen Sie eine vollständige Deklaration (nicht nur einen Eigenschaftsnamen) einschließen und KEIN Semikolon am Ende einfügen.
@supports
hat auch AND
, OR
und NOT
Logik verfügbar — 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, ohne JavaScript erforderlich, und wir können die gesamte Logik in einer einzigen CSS-Datei handhaben, wodurch HTTP-Anfragen reduziert werden. Aus diesem Grund ist es die bevorzugte Methode, um die Browser-Unterstützung für CSS-Features zu bestimmen.
JavaScript
Wir haben bereits früher ein Beispiel für einen JavaScript-Feature-Erkennungstest gesehen. Im Allgemeinen werden solche Tests mit einem von wenigen gemeinsamen Mustern durchgeführt.
Häufige Muster für erkennbare Features umfassen:
- Mitglieder eines Objekts
-
Überprüfen, ob eine bestimmte Methode oder Eigenschaft (typischerweise ein Einstiegspunkt in die API oder ein anderes Feature, das Sie erkennen) im übergeordneten
Object
existiert.Unser früheres Beispiel verwendete dieses Muster, um die Unterstützung für 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 mithilfe von
Document.createElement()
und überprüfen Sie dann, ob eine Eigenschaft darauf existiert.Dieses Beispiel zeigt eine Möglichkeit, die Unterstützung für die 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 an einem Element
-
Erstellen Sie ein Element im Speicher mithilfe von
Document.createElement()
und überprüfen Sie dann, ob eine Methode darauf existiert. Wenn ja, überprüfen Sie, welchen Wert sie zurückgibt. - Beibehaltung eines zugewiesenen Eigenschaftswertes durch ein Element
-
Erstellen Sie ein Element im Speicher mithilfe von
Document.createElement()
, setzen Sie eine Eigenschaft auf einen bestimmten Wert und überprüfen Sie dann, ob der Wert beibehalten wird.
Beachten Sie, dass einige Features jedoch als nicht erkennbar bekannt sind. In diesen Fällen müssen Sie einen anderen Ansatz verwenden, wie die Verwendung eines Polyfills.
matchMedia
Wir wollten an dieser Stelle auch das JavaScript-Feature Window.matchMedia
erwähnen. Dies ist eine Eigenschaft, die es Ihnen ermöglicht, Media Query-Tests innerhalb von JavaScript auszuführen. Es sieht folgendermaßen aus:
if (window.matchMedia("(max-width: 480px)").matches) {
// run JavaScript in here.
}
Als Beispiel verwendet unser Snapshot-Demo dies, um selektiv die Brick-JavaScript-Bibliothek anzuwenden und diese zu verwenden, um das UI-Layout zu handhaben, jedoch nur für das kleine Bildschirm-Layout (480px Breite oder weniger). Zuerst verwenden wir das media
-Attribut, um das Brick-CSS nur dann 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 Brick-Navigationsfunktionen nur auszuführen, wenn wir uns im kleinen Bildschirm-Layout befinden (in breiteren Bildschirm-Layouts kann alles auf einmal gesehen werden, daher müssen wir nicht zwischen verschiedenen Ansichten navigieren).
if (window.matchMedia("(max-width: 480px)").matches) {
deck.shuffleTo(1);
}