📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

Build a Pokedex with Vanilla HTML, CSS, and JavaScript

How to Become a Developer2:36:35

Transcription

Wir bauen diesen Pokédex mit Vanilla HTML, CSS und JavaScript. Wie wir sehen können, haben wir eine Liste unserer Pokémon. Wenn wir hier oben zum Beispiel nach Nummer suchen, erhalten wir das Pokémon Nidoking, das die Nummer 34 ist. Wenn wir löschen, erhalten wir alle Pokémon zurück. Wenn wir hier oben den Filter oder die Sortierung ändern, können wir zu Name wechseln und zum Beispiel nach CH suchen, was uns Glumanda und den Rest der Pokémon gibt, die CH enthalten. Sie können auch hier auf dieses X klicken, um alle Pokémon zurückzubekommen. Wenn wir zum Beispiel auf Glurak klicken, sehen wir die Detailseite des spezifischen Pokémon. Hier können wir auch zwischen Pokémon wechseln, indem wir die Pfeiltasten vor und zurück verwenden. Und hier können wir auch sehen, dass sich die Farbe dynamisch ändert, sowie alle Daten, die wir vom Pokémon haben, einschließlich des Namens, der Nummer, des Bildtyps, der Hintergrundfarbe und der Details. Dies sind alles gerenderte Daten, die wir von der Poke API erhalten. Dafür ist dieses Tutorial perfekt. Wir werden lernen, wie man eine API, eine offene API wie die Poke API, verwendet, wie man die Daten daraus erhält, oder wie all diese Daten hier, die Sie hier in Rohform sehen können. Wir werden lernen, wie man all dies abruft und all diese Daten für unsere eigenen Zwecke kostenlos nutzt. Zusätzlich hat dieser Pokédex ein vollständig responsives Design, wie wir sehen können, wenn wir die Bildschirmgröße verringern, und sieht auf dem Desktop und Mobilgeräten gut aus. Wenn wir auf ein Pokémon klicken, sehen wir, dass dasselbe für die Detailseite gilt und auf mobilen Geräten gut aussieht.

Um dieses Tutorial zu starten, ist es gut, dass Sie bereits etwas HTML, CSS und JavaScript kennen, da dies eher ein fortgeschrittenes Tutorial sein wird, das sich stark auf JavaScript konzentriert. Und wir werden kein CSS schreiben; wir werden es einfach aus unserer Referenzdatei importieren. Wenn Sie also lernen möchten, wie man den besten Pokédex baut, den Sie auf YouTube finden werden, und dabei viel Spaß haben und APIs lernen und etwas haben, das Sie in Ihrem Portfolio präsentieren können, um zukünftige Kollegen oder Arbeitgeber zu beeindrucken, dann legen wir los.

Das Erste, was wir tun werden, ist, einen neuen Ordner auf unserem Desktop zu erstellen, den wir Pokédex-Tutorial nennen werden. Sie können ihn nennen, wie Sie möchten, aber ich werde ihn so nennen. Dann werden wir unseren VS Code öffnen und unseren Ordner hier hineinziehen, was ihn in unserem Explorer öffnet. Als Nächstes gehen Sie in die Beschreibung dieses Videos und klicken auf den Link zum GitHub-Repo. Und hier werden wir den Quellcode herunterladen; hier werden wir ihn als Zip-Datei herunterladen. Sobald wir das heruntergeladen und entpackt haben, gehen wir hier in den Ordner. Wir werden den Assets-Ordner in unser Projekt ziehen; wir werden den Ordner kopieren, und das wird uns alle Bilder als SVGs für unsere Projekte liefern.

Dann werden wir unser Projekt starten. Wir werden eine neue index.html-Datei erstellen. Wir werden ein Ausrufezeichen eingeben, und das wird – lassen Sie uns auch unseren Explorer schließen – das wird auch auf Ansicht und Zeilenumbruch gesetzt, damit wir unseren gesamten Code auf einer Seite sehen, und das Ausrufezeichen gibt uns die Boilerplate-Vorlage. Das werden wir speichern. Lassen Sie uns einfach einen H1-Tag in den Body setzen und "Hallo zum Test" sagen. Und dann, wenn Sie Live Server noch nicht haben, gehen Sie hier zu den Erweiterungen und suchen nach einem Live Server, installieren Sie Live Server Private Weekday, das uns ermöglichen wird, mit unserem Projekt live zu gehen, so wie hier. Ich klicke darauf, und unsere Live-Website wurde in unserem Browser geöffnet. Wenn ich das jetzt mit "Tschüss" aktualisiere und speichere, sehen wir, dass die Website bei jedem Speichern aktualisiert wird. Sie können auch, wenn Sie möchten, Prettier herunterladen, das ist ein Code-Formatter, den ich verwende; er formatiert im Grunde meinen Code, entfernt Leerzeichen wie diese, wenn ich speichere. Wenn Sie also möchten, dass Ihr Code ähnlich aussieht wie meiner, das ist, was ich verwende, aber das ist eine optionale Erweiterung.

Zurück zu unserem HTML, lassen Sie uns unseren Test-H1 und H2 entfernen, speichern Sie das. Ich habe auch in meinem Tab hier mein Referenzprojekt geöffnet, das ich mit Netlify bereitgestellt habe. Sie können dies auch in der Beschreibung unten finden, wenn Sie es als Referenz ansehen möchten, um zu sehen, ob Sie richtig folgen und ob die Dinge in Ihrem Projekt genauso aussehen wie im fertigen Projekt. Wir werden also zwischen unserem Projekt und dem fertigen hin und her wechseln.

Also zurück in unser Projekt, das Erste, was wir im Body erstellen werden, ist ein Main-Element, um im Grunde all unseren Inhalt zu halten. Aber wir werden unserem Main-Element die Klasse "main" geben; diese Klasse werden wir später in unserem CSS-Styling verwenden. Und dann werden wir ihm einen Header und auch eine Klasse "header-hole" geben, weil wir auch einen Header für unsere Detailseite haben werden. Um Ihnen einen kleinen Überblick darüber zu geben, was wir im fertigen Projekt bauen werden: Wir haben unsere Hauptseite, das ist eine HTML-Seite, und wenn wir dann auf ein Pokémon klicken, ist dies eine weitere HTML-Seite, die Detailseite genannt wird. Wir haben also zwei HTML-Seiten und dann eine CSS-Datei, die alles styled, und wir haben auch drei JavaScript-Dateien: eine für die Suchfunktion, eine für den Hauptbereich hier, um alle Pokémon-Daten abzurufen, und dann eine weitere für die Detailseite, die wir hier sehen. Insgesamt werden wir also sechs Dateien in unserem Projekt haben.

Also zurück zu unserem HTML, wir werden innerhalb des Headers ein Div erstellen. Es wird eine Klasse "container" haben, und innerhalb dieses Divs werden wir ein weiteres Div mit der Klasse "logo-wrapper" haben. Und hier drinnen werden wir ein Bild mit einer Quelle von "./" haben; wir werden in den Assets-Ordner gehen und die Pokeball.SVG auswählen, und wir werden "Pokeball" als Alt-Text schreiben.

Gehen wir zurück zu unserer Datei hier; ich denke, es ist hier, es ist standardmäßig einfach weiß. Schauen wir uns Body Main an; wenn wir mit der rechten Maustaste auf die Seite klicken und das Div "container logo-wrapper" inspizieren, und wie wir hier sehen können, ist unser Pokeball da. Wenn wir unserem Body zum Beispiel etwas Stil geben würden, sehen Sie hier und Hintergrundfarbe, und lassen Sie uns Ihnen den Stil Blau geben, sehen wir, dass unser Pokeball da ist; er ist einfach weiß, die gleiche Farbe wie der Body. Dies ist auch Inline-Stil; wenn Sie damit nicht vertraut sind, können wir unser Styling direkt in HTML schreiben; wir brauchen keine separate CSS-Datei, aber es ist nicht wirklich Best Practice, dies zu tun, zumindest nicht mit Vanilla HTML, CSS und JavaScript; wir wollen die Dinge für Modularität und Lesbarkeit getrennt halten.

Dann unter unserem Bild werden wir einen H1-Tag hinzufügen und hier "Pokéfix" sagen. Dann unter dem Div, dem nächsten Div unter dem H1, werden wir ein weiteres Div hinzufügen, und dieses wird eine Klasse "search-wrapper" haben; das wird der Start unserer Suche sein. Hier drinnen werden wir ein Div mit der Klasse "search-wrap" haben, und dann innerhalb des Such-Wrappers werden wir ein Bild haben. Es wird eine Quelle von "./" in den Assets-Ordner haben; wir werden die Search.SVG nehmen, wir werden den Alt-Text "search icon" geben, und wir werden ihm auch eine Klasse "search-icon" geben, so wie hier.

Dann unter diesem Bild werden wir ein Eingabefeld haben, das der Ort sein wird, an dem wir unseren Suchtext schreiben. Es wird den Typ "text" haben, es wird eine Klasse "search-input" haben, eigentlich nur "search-input" und dann "boldD3-alts" so wie hier. Das werden wir verwenden, um dieses spezifische Eingabefeld zu stylen. Es wird auch einen Platzhalter haben, das ist ein Text, der da ist, bevor wir anfangen zu schreiben, von "Search" mit großem S, wir sehen, dass es jetzt auftaucht. Und schließlich wird es eine ID von "search-input" haben, so wie hier.

Dann unter dem Eingabefeld werden wir ein weiteres Bild haben; "./" in den Assets-Ordner, wir werden die Cross.SVG auswählen. Und das wird das "cross icon" als Alt-Text haben, sowie eine Klasse namens "search-close-icon" und auch eine ID von "search-close-icon". Und der Grund, warum wir sowohl Klasse als auch ID verwenden, ist, dass wir dieses Element mit der Klasse stylen und das Element in unserem JavaScript mit der ID referenzieren werden. Wie wir sehen können, fängt es hier in unserem Projekt an aufzutauchen; wir können hier schreiben, und der Platzhalter kommt zurück, wenn es leer ist; wir können diese Icons offensichtlich noch nicht verwenden, da sie nicht funktionsfähig sind.

Dann unter dem nächsten Div hier werden wir ein weiteres Div hinzufügen, und das wird eine Klasse "sort-wrapper" haben. Und hier drinnen werden wir ein weiteres Div haben; es wird eine Klasse "c-sort-wrap" haben und dann ein Bild hier drinnen mit der Quelle, die auf "assets/sorting.svg" zeigt, mit dem Alt-Text "sorting" und einer Klasse "sort-icon" und einer ID von "sort-icon". Das ist dieser Teil, den wir hier bauen, wo wir nach Name oder Nummer sortieren können.

Dann unter dem ersten Div werden wir ein neues Div erstellen. Es wird eine Klasse "filter-wrapper" haben, und es wird ein Paragraphen-Element hier drinnen haben, die Klasse "body-to-false", und auch innerhalb des Paragraphen werden wir "Sort by:" schreiben, Moment. Und dann unter dem Paragraphen werden wir ein weiteres Div mit der Klasse "filter-wrap" haben, und darin werden wir ein Div haben, und innerhalb dieses Divs werden wir ein Eingabefeld haben, das nicht funktioniert hat. Wir werden ein Eingabeelement vom Typ nicht "text", sondern "radio" haben, weil dies Radio-Buttons sein werden, die wir hier sehen, die wir auch im fertigen Pokédex sehen können, sowie einen Typ. Es wird eine ID von "number" haben, und es wird einen Namen von "filters" haben. Es wird einen Wert der Nummer haben, und es wird das "checked"-Attribut haben, was bedeutet, dass es standardmäßig ausgewählt ist.

Dann hier drunter werden wir ein Label für die Nummer haben, und es wird eine Klasse von "all-the-three-false" haben, und es wird eine Nummer darin haben. Und dann unter diesem Div werden wir ein weiteres Div erstellen. Es wird ein weiteres Eingabefeld vom Typ "radio" haben, ID "name", Name "filters", Wert "name". Und dann hier drunter werden wir ein weiteres Label für "name" hinzufügen und die Klasse "body-three-fonts", und hier drinnen werden wir den Namen schreiben. Das gibt uns also die Möglichkeit, nach Nummer oder Name zu sortieren. Offensichtlich sortiert es jetzt nichts; es ermöglicht uns nur, auf diese Radio-Buttons zu klicken, aber wir werden diese Funktionalität später mit JavaScript nutzen und erstellen. Wie wir sehen können, wenn ich aktualisiere, wenn ich zu "Name" gehe, aktualisiere ich, die Sortierung hat standardmäßig das "number"-Attribut, das liegt daran, dass es hier standardmäßig ausgewählt ist.

Dann können wir ganz nach unten zu unserem Header scrollen, und unter unserem Header werden wir einen Abschnitt hinzufügen. Und hier werden wir die Klasse "Pokemon-list" sagen, und hier werden unsere tatsächlichen Pokémon gerendert. Aber wir müssen nicht das HTML für all diese Pokémon erstellen; wir müssen nur eine Vorlage für sie erstellen, und dann werden die Daten dynamisch von der API gefüllt. Also als Nächstes ein Div hier drunter mit einer Klasse "container", und dann das Div darunter wieder oder innen mit einer Klasse "list-wrapper". Und dann unter dem Container-Div haben wir ein weiteres Div, es ist eine ID, eine weitere "not-found-message". Dies wird eine Nachricht sein, wenn wir hier sehen, lassen Sie uns sehen, wenn ich einfach etwas eingebe, das nicht existiert, dies ist eine Pokémon-ID, Ihr Name, es existiert nicht, wir erhalten diese "Pokémon nicht gefunden"-Nachricht, und das ist diese Nachricht hier, die wir standardmäßig ausblenden, aber wenn wir etwas eingeben, das uns keine Ergebnisse liefert, wird sie im Grunde angezeigt. Wenn ich also "zwei" sage, erscheint es; wenn ich "22" sage, erscheint Pokémon, und weil wir unsere maximale Anzahl an Pokémon, die von der API abgerufen werden sollen, auf 151 gesetzt haben, obwohl Sie das selbst wählen können, wenn ich jetzt "222" eingebe, wurden keine Pokémon gefunden, also "Pokémon nicht gefunden". Und ob Sie es glauben oder nicht, das ist das gesamte HTML, das wir für unsere Hauptseite benötigen, und das ist vollständig, denn der Rest sind nur Detailbilder hier, die wir in unserem JavaScript erstellen werden.

Also, lassen Sie uns unsere JavaScript-Datei erstellen. Also zurück in unser Projekt und zurück in unseren Index, lassen Sie uns durch Öffnen unseres Explorers unsere JavaScript-Datei erstellen, die wir verwenden werden, um alle Pokémon abzurufen, damit wir sie tatsächlich sehen können. Wir werden diese Datei "pokemon.js" nennen und dann zurück zu unserer index.html wechseln. Wir werden unsere JavaScript-Datei mit unserer HTML-Datei verknüpfen, indem wir ein Skript unter unserem Titel schreiben; wir werden dem eine Quelle geben und auf unsere pokemon.js-Datei verweisen. Lassen Sie uns auch daran denken, das "defer"-Attribut hier hinzuzufügen, damit das HTML vor dem JavaScript ausgeführt wird, obwohl das JavaScript hier oben in der HTML-Datei ist und HTML standardmäßig von oben nach unten gelesen und ausgeführt wird. "Defer" bewirkt, dass JavaScript übersprungen wird, bis zur letzten Instanz im Grunde, und dann vermeiden wir Fehler in unserem JavaScript-Code, weil wir Elemente in HTML referenzieren würden, die nicht existieren, wenn das JavaScript ohne dieses Attribut hier, "defer", ausgeführt würde. Lassen Sie uns unser JavaScript hier ausprobieren, indem wir "console.log('Tests')" schreiben, und dann lassen Sie uns durch Inspizieren und Gehen zur Konsole öffnen, und wir sehen, dass "Test" ausgeführt wird, großartig. Also, lassen Sie uns den "console.log test" entfernen und anfangen, unser JavaScript zu schreiben.

Das Erste, was wir schreiben werden, ist die Konstante, und wir werden sie "MAX_POKEMON" in Großbuchstaben nennen, und wir werden 151 sagen. Im Grunde ist dies unsere Konstante für die maximale Anzahl von Pokémon, die wir von der Pokémon-API abrufen werden. Wie Sie sehen können, ist Mew das 151. Pokémon, und das liegt daran, dass wir diese MAX_POKEMON-Konstante hier setzen.

Dann werden wir Konstanten erstellen. Wir werden hier DOM-Elemente definieren, die wir verwenden, um im Grunde die HTML-Elemente zu referenzieren, und wir werden JavaScript-Konstanten für sie in unserer Datei hier erstellen. Die Art, wie wir das tun, ist, dass wir das Dokument ansprechen und dann den "querySelector" verwenden können, und dann können wir hier die Klasse "list-wrapper" ansprechen. Lassen Sie uns auch sicherstellen, dies in Anführungszeichen zu setzen, und wir können auch unseren Zeilenumbruch einschalten. Hier können wir also mit "querySelector" entweder Klassen mit der Punktnotation oder IDs mit den Hashtags auswählen. Das ist also unser "list-wrapper"; wenn wir hier zu unseren Elementen gehen, können wir sehen, dass wir "Pokemon list-wrapper" haben, das ist hier, was natürlich derzeit leer ist, weil wir noch keine Pokémon hineingelegt haben.

Dann werden wir neue Konstanten namens "searchInput" erstellen, die gleich sein werden, und wir werden dies herunterkopieren: "document.querySelector", und anstelle des "list-wrapper" wird das "#search-input" sein. Lassen Sie uns dies auch dreimal mit Shift+Alt+Pfeil nach unten kopieren. Das Nächste wird "const numberFilter = document.querySelector('#number')" sein. Das Nächste wird "nameFilter" sein, und hier werden wir "#name" sagen. Das Letzte wird "notFoundMessage" sein, und das wird "#not-found-message" sein. Und beachten Sie, dass wir hier Camel Case verwenden, wo wir jedes Wort nach dem ersten großschreiben.

Dann werden wir eine Variable namens "allPokemons" erstellen, die einem leeren Array gleich sein wird, und das ist der Ort, an dem wir alle unsere Pokémon speichern werden, wenn wir sie abgerufen haben.

Dann der interessante Teil: Wenn wir gehen, können Sie zu pokeapi.com gehen, und dies ist die API, die wir verwenden werden. Im Grunde hat jemand diese API öffentlich zugänglich gemacht, und dann, lassen Sie uns sehen, wenn wir dies öffnen, können wir die API hier sehen; tatsächlich ist dies für den Ditto-Charakter. Wenn wir also hier zum Beispiel Glumanda schreiben, sehen wir, dass wir die Daten für Glumanda laden, aber wir können auch die Daten für die gesamte Poke API laden. Also, lassen Sie uns das tun; lassen Sie uns hier kopieren, lassen Sie uns es hier einfügen und lassen Sie uns einfach Glumanda entfernen, und dann können wir sehen, wenn wir "pokeapi/api/v2/pokemon" haben, weil es auch eine V1 gibt, sehen wir, dass wir im Grunde 1281 Pokémon erhalten. Und was Sie hier sehen, sind JSON-formatierte Daten; wenn ich hier auf "raw" drücke, können wir sehen, wie es aussieht. Und wenn ich in der Konsole inspiziere und dann hier zum Netzwerk gehe und aktualisiere, sehen wir hier, dass wir eine Anfrage an die Poke API senden; wir senden eine GET-Anfrage. Das ist also im Wesentlichen das, was wir tun, wenn wir unsere Pokémon abrufen; wir sagen: "Hey, geh zu dieser URL und hol dir Daten", als vereinfachte Erklärung dessen, was wir tun, aber vorerst ist das alles, was an Verständnis nötig ist. Wir senden im Grunde eine Anfrage auf die gleiche Weise, wie wenn wir zu einer URL gehen und senden: "Hey, lass mich zu dieser Adresse hier gehen", das ist dasselbe, was wir hier tun, und dann, anstatt nur einen Startbildschirm mit Schaltflächen und so weiter zu bekommen, bekommen wir eine Menge Daten direkt auf unserem Bildschirm. Und hier, wenn ich auf "Vorschau" klicke, können wir den Namen hier sehen; also Ergebnisse, wir haben Bisasam, wir haben Bisaknosp, wir haben Bisaflor. Im Grunde gibt uns dies die ersten 19 Pokémon auf dieser Seite. Wie jede API hat sie bestimmte eingebaute Funktionen. Zum Beispiel sehen wir hier, dass wir die Adresse "v2/pokemon/ditto" haben; wir können auch "zwei" eingeben und "Senden" sagen, das wird uns Bisaknosp geben. Wir können also bereits Zahlen eingeben, wir können den Namen eingeben. Sie sehen, es gibt hier auch weitere Hinweise, wie man die API verwendet, zum Beispiel "pokemon?limit=100000&offset=0". Im Grunde können Sie hier in der Dokumentation lesen, was all diese Schlüsselwörter tun; Sie können lesen, wie man im Grunde Pokémon abruft, Sie können lesen, wie man Beeren abruft, Sie können lesen, wie man alle verschiedenen Arten von Pokémon-Gegenständen abruft, die in dieser Pokémon-API gespeichert sind, und sie werden im Grunde verschiedene URLs mit verschiedenen Schlüsselwörtern darin haben, getrennt durch diesen Schrägstrich. Wenn wir also zum Beispiel alle Pokémon hier haben wollen, können wir dieses Limit und dann hunderttausend hinzufügen, denn das ist weit mehr als die existierenden Pokémon, und dann können wir sehen, wenn wir das in unseren Browser eingeben, sehen wir, dass wir im Grunde alle existierenden Pokémon erhalten, bis zu, ich schätze, eintausendzweihundertirgendwas Tausend. Oh, es ist tatsächlich viel mehr, da ich als Kind Pokémon mochte. Wow, es gibt viele Pokémon, also gibt es anscheinend 10.271 Pokémon. Jetzt werden wir uns nur um die 151. kümmern, das macht die Arbeit für uns einfacher. Aber im Grunde können Sie über eine API verschiedene Daten von der API abrufen, indem Sie ihr verschiedene Anfragen in Form einer URL geben.

Wie verwenden wir das also in unserem JavaScript? Nun, wir werden eine eingebaute Methode in JavaScript namens "Fetch" verwenden, und Sie sehen, dass dies eine Funktion ist, "Fetch", und dann können Sie "request info" eingeben. Wie wir das machen, sagen wir "fetch" und dann Klammern, und dann werden wir hier Backticks verwenden, und dann werden wir hier Backticks schreiben, und innerhalb der Backticks werden wir "https://" schreiben, und dann werden wir im Grunde diese Pokémon-API schreiben, so dass wir das Ganze hier bis zum Limit kopieren können; wir können das dort einfügen, so dass uns das unsere Pokémon-API gibt, die auf die Pokémon-API zugreift. Und dann, anstatt hier einfach 151 zu schreiben, was wir könnten, werden wir auf diese Konstante zugreifen, die wir hier erstellt haben, denn dann, wenn wir mehr oder weniger Pokémon abrufen wollen, können wir einfach diese Konstante hier ändern, anstatt die eigentliche HTTP-Anfrage hier zu ändern. Anstatt also unsere MAX_POKEMON hier als 151 fest zu codieren, werden wir etwas namens Template-Literale verwenden. Wir schreiben also ein Dollarzeichen und dann geschweifte Klammern, und dann sehen wir, dass sich die Farbe hier geändert hat, denn jetzt können wir hier drinnen Konstanten referenzieren, weil sonst, wenn wir nur innerhalb der Klammern hier schreiben, es nur HTML sein wird, es wird nur als String erkannt werden, aber jetzt können wir hier drinnen tatsächlich Daten referenzieren. Wir werden also "MAX_POKEMON" sagen, und dann schlug es "MAX_POKEMON" vor. Ich werde speichern und dann werden wir ".then" sagen und dann geschweifte Klammern und dann zweimal Klammern. Ich werde sagen, wir werden die Antwort nehmen, die wir erhalten haben, denn jetzt werden wir von der Pokémon-API die ersten 151 Pokémon abrufen, und dann werden wir eine Antwort erhalten, und dann werden wir eine weitere eingebaute Methode namens "then" verwenden, die im Grunde sagt: "Nimm dann die Antwort und mache etwas mit dieser Antwort", und wir werden hier einen Pfeil für das nächste verwenden, um im Grunde zu sagen: "Nimm die Antwort, wandle sie in JSON um", und dann werde ich wieder in eine neue Zeile gehen. Ich füge im Grunde nur der Funktion hinzu, die wir bereits haben. Dies ist eigentlich so geschrieben, aber es macht es viel einfacher zu sehen, was passiert, wenn wir die nächste Kette im Befehl hier in einer neuen Zeile schreiben, aber alles läuft im Grunde nacheinander ab: Zuerst führen wir dies aus, dann führen wir dies aus, dann führen wir das aus, also trennen wir es einfach mit einer neuen Zeile, um klarer zu sehen, was bei jedem Schritt passiert. Nachdem wir also unsere Antwort genommen und in JSON umgewandelt haben, dann wieder doppelte Klammern, werden wir die Daten nehmen, die wir erhalten, und wir werden weitere Logik anwenden, dann führen wir eine weitere Pfeilfunktion aus, und dann werden wir "allPokemons" sehen, das ist die Variable, die wir hier oben erstellt haben, das ist ein leeres Array; wir werden das mit den Daten füllen, die wir gerade erhalten haben, indem wir in "data.results" gehen.

Woher bekomme ich diese Daten? Nun, wenn wir die Daten hier so in der Konsole protokollieren und wir gehen zurück zu unserer Seite hier und gehen zur Konsole, sehen wir, dass, wenn wir auf die Daten zugreifen, die wir von der API erhalten haben, dies das ist, was wir erhalten. Wir erhalten im Grunde die Rohdaten von der Poke API, das ist sozusagen das Top-Level-Ergebnis oder die Informationen, die wir erhalten, und hier haben wir alle Informationen für die 151 Pokémon, ganz bis zu Mew, wie wir hier sehen können, beginnend mit Nummer Null, Bisasam. Und dann, wenn ich "data.results" sage, sehen wir, dass wir eine weitere Ebene tiefer gelangen. Wenn ich jetzt öffne, gehen wir weiter in die Antwort hier hinein, also lassen Sie mich einfach beide in der Konsole protokollieren, damit wir sehen können, dass wir immer tiefer in unser Ergebnis gehen. Nummer eins, wir bekommen die Daten; Nummer zwei, wir bekommen das Daten-Ergebnis, und jetzt sehen wir, dass "data.results" nur eine Sammlung ist, es ist ein großes Array mit einer Sammlung von – Sie sehen hier, vielleicht etwas klein, aber es ist ein Array, wie wir hier sehen können, mit einer Reihe von Objekten darin, und jedes Objekt enthält tatsächlich ein Pokémon. Wenn wir also alles nach unten verschieben, sagen wir "data.results" und dann eckige Klammern "null", und wir speichern erneut, sehen wir, dass wir das erste Objekt innerhalb des oder eigentlich das erste Array innerhalb der Daten-Ergebnisse erhalten, das Bisasam ist. Jetzt sind wir also einen Schritt weiter, und dann kopieren wir wieder nach unten. Wenn wir "data.results" nehmen, das erste in den Ergebnissen, und wir sagen ".name", sehen wir, dass wir Bisasam erhalten, weil innerhalb dieses, das ist dieser Teil hier, wir sehen, dass wir "name" und "URL" haben, und wenn wir dann einfach den Namen danach wieder protokollieren, greifen wir im Grunde einen Schritt weiter zu, wir erhalten den Wert darin. Was passiert, wenn wir zu "URL.URL" gehen? Nun, dann erhalten wir diesen Link zu Bisasams eigener API; wenn wir darauf klicken, erhalten wir eine weitere API, einen Abschnitt der API im Grunde, auf den wir jetzt weiter zugreifen können. Ich hoffe also, das macht Ihnen ein wenig Sinn, wie das funktioniert, wie wir darauf zugreifen. Wir rufen hier im Grunde die Poke API ab; wir sagen, wie viele Pokémon wir abrufen wollen, und dann erhalten wir dieses ganze Objekt hier, wie wir hier sehen können, es heißt Objekt, und innerhalb dieses Objekts haben wir ein Array von 151 Pokémon, das ist das, was wir hier im Ergebnis protokollieren. Sie können ein Array der Länge 151 sehen; innerhalb dieses Arrays haben wir eine Reihe von Objekten, jedes enthält ein Pokémon, und das ist das, was wir hier in der Konsole protokollieren, und wir protokollieren sowohl den Namen als auch die URL, die im Grunde Schlüssel-Wert-Paare innerhalb dieser Pokémon sind. Dies ist also eine sehr standardmäßige API; sie kann viele Formen haben, sie kann sehr groß sein, sie kann viele, viele, im Grunde verschachtelte Dinge haben, wie dieses eine innerhalb des anderen, innerhalb des anderen, innerhalb des anderen, aber so sieht eine API im Grunde aus. Wenn wir hier zum Netzwerk gehen, können wir auch zum Pokémon-Limit hier gehen, das ist die Anfrage, die wir gesendet haben, und wir sehen die Vorschau, wir sehen die Ergebnisse hier, was eine weitere Möglichkeit ist, wie wir es direkt mit unserem Konsolen-Logging ansehen können; wir können sehen, was wir von der API zurückerhalten, und hier, wenn wir auf die Antwort klicken, sehen wir, dass es tatsächlich in seiner tatsächlichen Form im JSON-Format ausgedruckt wurde. Machen Sie sich also keine Sorgen, wenn das an diesem Punkt etwas überwältigend ist; wenn Sie zum ersten Mal mit APIs zu tun haben, kann es etwas verwirrend sein, aber da wir damit arbeiten werden, denke ich, wird es sich einfügen, und auch wenn wir dazu kommen, die echten Daten für etwas zu verwenden und Sie die Ergebnisse auf der Seite sehen werden, wird es immer mehr Sinn ergeben.

Also, jetzt haben wir unsere Daten, was machen wir eigentlich damit? Nun, wir füllen es natürlich in unsere Pokémon, alle Pokémon hier, also konnten wir jetzt tatsächlich die Daten von der Poke API abrufen und haben sie jetzt in unserer Variablen hier gespeichert. Anstatt es also von hier aus in der Konsole zu protokollieren, lassen Sie uns "allPokemons" so lange ausführen, und es erscheint "siebel". Wir sehen, wir haben ein Array, dieses Array ist natürlich leer, wir müssen es hier hineinlegen, so wie hier. Dann, wenn wir sehen, dass wir "allPokemons" hier in der Konsole protokollieren, gibt es uns im Grunde die Daten zurück, die wir abgerufen haben. Also großartig, jetzt können wir das entfernen.

Dann werden wir eine Funktion namens "fetchPokemonDataBeforeRedirect" erstellen, und dann werden wir ihr ein Argument geben, und wir werden "ID" sagen; wir werden ihm ein Argument für jedes einzelne Pokémon geben, Sie wissen schon, Glumanda mit ID 1 usw. usw. usw. Aber der knifflige Teil bei der tatsächlichen Verwendung von APIs ist, dass, wenn Sie Ihre App hier erstellen, wie in unserer fertigen App, wenn Sie klicken oder eigentlich, wenn Sie die App zum ersten Mal laden, es einen kleinen Moment dauert, wie Sie hier sehen können, gibt es eine kleine Verzögerung; es dauert einen kleinen Moment, obwohl es kurz ist, es dauert einige Zeit für die Daten zwischen dem Senden der Fetch-Anfrage und dem Gehen zur Poke API und dem Abrufen der Daten zurück. Wenn wir hier im Netzwerk sehen können, wenn ich hier aktualisiere, sehen wir, dass es hier tatsächlich Zeit gibt, auch wenn es nur 40 Millisekunden, 47 Millisekunden sind, Sie wissen schon, das Pokémon, die 27 Millisekunden, obwohl diese sehr kurz und im Grunde für das menschliche Auge fast unsichtbar sind, für einen Computer, für unseren Browser ist es einige Zeit. Und was wir dann tun müssen, wenn wir mit APIs arbeiten, ist, dass wir etwas namens asynchrone Funktionen verwenden müssen, und im Grunde tun sie, dass sie uns erlauben, Code auszuführen und dann im Grunde die nächste Zeile JavaScript-Code zu verzögern, bis wir tatsächlich die Daten abgerufen haben, die wir wollen. Denn wenn ich jetzt zum Beispiel "console.log(someData)" sagte, aber dann sagte ich "someData", lassen Sie uns sehen, "const someData = API data from URL", also, wenn ich Daten von der URL erhalte, zum Beispiel diese hier, und ich setze "const someData", könnte ich möglicherweise nicht abrufen, nun, wenn diese Daten sehr groß sind oder wenn es nur eine etwas langsame Verbindung ist, könnte ich möglicherweise nicht tatsächlich alle Daten schnell genug in diese "someData" legen, bevor ich Zeile 18 ausführe. Wenn ich also Zeile 17 in JavaScript ausführe, läuft sie sehr schnell, im Grunde sofort, eine Zeile nach der anderen, und dann läuft Zeile 17 und dann läuft Zeile 18 sofort. Wenn also "someData" noch nicht existiert, wird Zeile 18 hier, Zeile 18, mir einen Fehler geben, weil "someData" nicht existiert oder leer ist, und das kann viele Probleme verursachen, wenn wir davon ausgehen, dass alles im Grunde so schnell wie möglich läuft. Wenn Sie also mit APIs arbeiten, wenn Sie mit einer Art größerem Projekt arbeiten, bei dem Sie Daten von irgendwoher abrufen, müssen Sie asynchrone Funktionen verwenden, und was das tut, ist, dass es im Grunde sagt – es ist jetzt nicht so geschrieben, ich gebe Ihnen nur ein Beispiel, wir werden es gleich schreiben – aber wenn dies ein asynchrones Setup wäre, würden wir im Grunde sagen: "Versuche, diese Konstante 'someData' zu bekommen; wenn du diese Daten hast, dann werden wir die nächste Zeile ausführen, aber bis du sie hast, wirst du die nächste JavaScript-Zeile pausieren und warten, bis wir die Daten haben, die wir brauchen." Das ist also im Wesentlichen, was asynchrone Funktionen tun.

Das ist genug Theorie, sehen wir es uns in der Praxis an. Die Art, wie wir das tun, ist im Grunde, dass wir sagen: "async function fetchPokemonDataBeforeRedirect", und dann geben wir ihm eine ID für jedes Pokémon, und wir werden "try" sagen, und dann werden wir "const" schreiben, und hier werden wir etwas namens Destrukturierung verwenden, wo wir mehrere Konstanten auf einmal erstellen, indem wir sie in Arrays setzen, also "pokemonSpecies" und "pokemon", und im Grunde definieren wir sie jetzt als Konstante "pokemon" und Konstante "pokemonSpecies", und sie werden gleich sein. Wir werden eine weitere asynchrone Funktionalität verwenden, "await", und das ist im Grunde diejenige, die verzögert. Sie werden diese Pokémon, "const pokemon" und "const pokemonSpecies", erstellen, wenn Sie die Daten haben. Also "await", und hier werden wir ein weiteres "Promise.all" sagen und dann Klammern und dann eckige Klammern, und dann werden wir "fetch" sagen, Klammern, und dann werden wir hier hochgehen und diese ganze Fetch-Anfrage hier hoch kopieren und sie hier einfügen, und wir werden alles nach "pokemon" löschen, und hier werden wir sagen: "/", wir werden "${ID}" schreiben, und wir werden ihm eine ID geben, die ID des Pokémon, und dann werden wir ".then" schreiben und weitere doppelte Klammern. Wir werden die Antwort hier nehmen, und wir werden eine Funktion ausführen; wir werden sagen: "response => response.json()". Wenn das also etwas verwirrend wird, machen Sie sich keine Sorgen, ich werde es gleich erklären, aber es ist auch eine Syntax, an die Sie sich gewöhnen müssen. Dies wird also im Grunde eine asynchrone Funktion genannt; wir haben "try", wir haben "await", wir haben ein "Promise", denn wenn wir die Daten abrufen, werden uns im Grunde Daten versprochen, aber wir haben sie noch nicht erhalten, also sagen wir im Grunde: "Dies ist ein Promise, dass wir Daten erhalten werden, obwohl Sie sie noch nicht haben, und sie werden von hier kommen", und dann rufen wir im Grunde diese Daten ab und wandeln sie in JSON um, das wir in unserem JavaScript lesen können. Und dann nach den Klammern hier werden wir sagen, dass wir abrufen werden, und dann werden wir diese Fetch-Anfrage hier ganz bis zu "json" kopieren, also fügen Sie das dort ein, und hier werden wir "pokemon-species/${ID}" sagen, dann werden wir die Antwort nehmen und wir werden das auch in JSON umwandeln. Hier haben wir einige übrig gebliebene Klammern; eigentlich brauchen wir diese blauen Klammern hier nicht zwischen oder nach unserer Pfeilfunktion hier, also entfernen Sie diese so wie hier. Dann, wenn wir hierher kommen, werden wir "true" zurückgeben, und wenn nicht, wenn etwas bei unserem Abruf der Daten fehlschlägt, werden wir den Fehler abfangen und dann den Fehler mit der Nachricht "Failed to fetch Pokemon data before redirect" in der Konsole protokollieren.

Okay, wenn wir also im Grunde hier auf das Pokémon klicken, ist die ganze Funktion hier dafür da, dass wir, wenn wir hier auf ein Pokémon klicken, diese Funktion verwenden, und wenn Sie sehen, es dauerte einige Zeit, bevor ich geklickt habe, lassen Sie uns sehen, das ist Glutexo, es dauert einige Zeit, bevor Glutexos Daten von der Pokémon-API abgerufen werden. Also hier rufen wir die Pokémon-Daten vor der Weiterleitung ab, und wir leiten zu ID 5 weiter, wie Sie hier sehen können, wenn ich zu Schiggy ID 8 gehe. Das ist also das, was wir hier in dieser asynchronen Funktion tun: Wir versuchen, die Daten sowohl für das Pokémon als auch für die Pokémon-Spezies abzurufen, und dann geben wir "true" zurück, wenn es funktioniert, wir verlassen sozusagen die Funktion hier, und wenn nicht, geben wir einen Fehler zurück. Nein, wir bekommen den Fehler hier nicht, weil es tatsächlich funktioniert, die Daten abzurufen.

Die nächste Funktion, die wir erstellen werden, wird "displayPokemon" heißen, es sind mehrere, und wir werden ein Pokémon hier hereinnehmen, und wir werden im Grunde die Liste hier erstellen; wir werden die Pokémon-Listen abrufen. Also werden wir sagen, "listWrapper.innerHTML" wird gleich einem leeren String sein, den wir bereits erstellt haben, so dass wir jedes Mal, wenn wir abrufen, einfach das innere HTML leeren, was wir hier sehen können, "listWrapper", das ist das, und jetzt ist es standardmäßig leer. Dann werden wir sagen: "forEach" Pokémon, für jede doppelte Klammer, ich werde das Pokémon nehmen, wir werden eine Pfeilfunktion ausführen, wir werden sagen: "const pokemonID = pokemon.url.split('/')[6]", und wir wollen die URL zwischen diesem und, Entschuldigung, diesem Schrägstrich aufteilen. Wie wir hier sehen können, haben wir viele Schrägstriche in der URL hier, und was "split" tut, ist, dass es uns im Grunde ein Array mit all diesen verschiedenen Strings gibt, die durch die Schrägstriche getrennt sind, und wir wollen zum sechsten, zur sechsten Position gehen. Wir können hier sehen, dass wir eins, zwei, drei, vier, fünf, sechs Schrägstriche verwenden, um zu Ditto zu gelangen. Was wir also hier in unserem "split" sagen, ist nach dem sechsten Schrägstrich, das ist im Grunde das, worauf wir hier zugreifen, das ist die Pokémon-ID oder Ditto, oder Sie wissen schon, wenn wir "drei" schreiben, wird das Nummer drei sein. Dann werden wir sagen: "const listItem = document.createElement('div')"; wir erstellen hier ein HTML-Element in unserem JavaScript, und wir werden sagen, das wird ein Div sein, und dann "listItem.className = 'list-item'"; wir werden dorthin gehen und wir werden sagen, geben Sie diesem "list-item", und das ist, wenn wir hier inspizieren, sehen wir, dass es eine Klasse namens "list-item" hat. Dann werden wir in das Listenelement gehen, wir werden "innerHTML" sagen, das ist vorerst noch leer, und wir werden zwei Backticks schreiben; es ist sehr wichtig, dass es Backticks sind, sonst können wir keine Daten in unser HTML einfügen. Also innerhalb dieser Backticks werden wir tatsächlich das HTML erstellen, das hier drinnen ist, innerhalb jedes Listenelements. Also hier drinnen werden wir ein Div zum Starten und ein schließendes Div haben, und dieses Div wird eine Klasse gleich "number-rep" haben, und dann innerhalb dieses Divs werden wir ein Paragraphen-Element haben, öffnenden und schließenden Tag, und es wird eine Klasse von "caption-false" haben, und innerhalb des Paragraphen werden wir "#" und dann "${pokemonID}" schreiben. Dann kopieren wir dieses Div hier herunter, und hier werden wir die Klasse in "image-wrap" ändern, und anstelle eines Paragraphen hier werden wir ein Bild geben, und dann ist das Bild ein selbstschließendes Element, also braucht es nur einen Tag. Aber stellen Sie sicher, den Schrägstrich am Ende hier hinzuzufügen. Also werden wir hier eine Quelle hinzufügen, gleich, und wir erhalten die Quelle für die Bilder tatsächlich von einer anderen Website; sie wird "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/dream-world/${pokemonID}.svg" heißen, und dann danach werden wir einen Alt-Text hinzufügen; er wird gleich "${pokemon.name}" sein. Speichern Sie das. Dann kopieren wir das erste Div wieder, fügen es hier drunter ein, und hier werden wir "name-wrap" sagen, wir werden ihm eine Klasse "body-three-fonts" geben, und hier wird es "pokemon.name" sagen. Dann hier drunter werden wir das Listenelement ansprechen, wir werden einen Event-Listener hinzufügen, wir werden sagen "click", wenn wir auf ein Element klicken, werden wir eine asynchrone Funktion ausführen und sagen: "const success = await fetchPokemonDataBeforeRedirect(pokemonID)", und dann, wenn "success", werden wir dem Fenster im Grunde den Browser hier umleiten: "window.location.href = `./detail.html?id=${pokemonID}`". Hier werden wir also später eine detail.html-Seite erstellen, das wird unsere Detailseite sein, und dann wird die ID der Pokémon-ID für jede ID hinzugefügt. Im Grunde laden wir so die verschiedenen Daten basierend darauf, welches Pokémon wir wollen, aber behalten die gleiche HTML-Detailseite bei. Dann schließlich wollen wir den "listWrapper" ansprechen und das erstellte Listenelement anhängen.

Also, jetzt haben wir unsere "displayPokemons"-Funktion bereit. Am Anfang leeren wir den "listWrapper", damit, falls wir die Seite neu laden, keine zusätzlichen Pokémon zu den bestehenden hinzugefügt werden. Dann erstellen wir für jedes Pokémon die HTML-Struktur; wir verwenden die IDs und nutzen diese, um jedes Pokémon anzusprechen. Und dann fügen wir ein Klick-Ereignis hinzu, das uns zur Detailseite jedes Pokémon führt, wenn wir es von der Hauptseite aus anklicken. Und dann fügen wir schließlich all diese Listenelemente zum "listWrapper" hinzu. Und jetzt müssen wir diese "display"-Funktion tatsächlich innerhalb unserer Fetch-Anfrage hier aufrufen. Also werden wir "displayPokemons(allPokemons)" sagen, und wir speichern, und voilà, wir haben alle unsere Pokémon abgerufen. Wie cool ist das! Wir erhalten Daten von unserer Poke API mit unserer ganz eigenen Funktion hier. Also jetzt können wir diese Funktion schließen oder minimieren, es ist einfacher zu sehen; Sie können diese asynchrone Funktion auch minimieren. Wir erstellen also ein leeres Array, wir rufen Daten ab und legen sie in dieses Array, und dann rufen wir hier die "displayPokemons"-Funktion auf, und dann, wenn wir auf die Pokémon klicken, werden wir diese "fetchPokemonDataBeforeRedirect"-Funktion aufrufen.

Als Nächstes, nach unseren "displayPokemons", wollen wir diese Suchfunktion hier tatsächlich aktivieren. Also werden wir "searchInput.addEventListener('keyup', handleSearch)" sagen, weil das darauf hört, wann wir eine Taste gedrückt und dann tatsächlich losgelassen haben, und wir werden eine Funktion namens "handleSearch" aufrufen, die wir noch nicht erstellt haben. Und dann lassen Sie uns diese Funktion "handleSearch" erstellen; es wird eine Standardfunktion sein, keine asynchrone Funktion. Dann werden wir sagen: "const searchTerm = searchInput.value.toLowerCase()"; wir sagen also, wir werden den Such-Input nehmen, ups, das wird der Wert sein, wir werden den Wert nehmen, den wir hier eingeben, und falls ich irgendwelche Großbuchstaben hinzufüge, wird alles in Kleinbuchstaben umgewandelt. Dann werde ich sagen: "let filteredPokemons"; wenn "numberFilter.checked" ist, was bedeutet, dass wir hier nach den Nummern suchen, dann "filteredPokemons = allPokemons.filter(pokemon => { const pokemonID = pokemon.url.split('/')[6]; return pokemonID.startsWith(searchTerm); })". Und dann, wenn der Filter, der Nummernfilter, nicht ausgewählt ist, lassen Sie uns hier die Else-Anweisung erstellen, also "else if (nameFilter.checked) { filteredPokemons = allPokemons.filter(pokemon => pokemon.name.toLowerCase().startsWith(searchTerm)); }". Und wenn das nicht funktioniert, "else", im Grunde ist das, wenn keiner ausgewählt ist, dann werden wir alle anzeigen: "filteredPokemons = allPokemons"; es ist eine geschweifte Klammer hier, so wie hier. Dann werden wir die Pokémon mit den gerade erstellten "filteredPokemons" anzeigen. Und dann, wenn "filteredPokemons.length" gleich Null ist, werden wir sagen: "notFoundMessage.style.display = 'block'", weil diese "not-found"-Nachricht, Sie erinnern sich, die wir am Anfang hier gemacht haben, wir werden sie standardmäßig in unserem CSS ausblenden, und dann, wenn nichts in unserer Suche angezeigt wird, weil wir vielleicht etwas geschrieben haben, oh, lassen Sie uns sehen, es funktioniert bereits, lassen Sie uns sehen, noch nicht ganz, natürlich sind es hier Zahlen, wir sehen, dass unser Filter basierend auf den Zahlen funktioniert, und wenn wir auf den Namen klicken, lassen Sie uns sehen, Bisasam, es funktioniert noch nicht ganz. Nun, lassen Sie uns das überprüfen, aber auf jeden Fall, wenn nichts angezeigt wird, erhalten wir unsere "Pokémon nicht gefunden"-Nachricht, und standardmäßig werden wir sie ausblenden: "notFoundMessage.style.display = 'none'". Also, der Namensfilter funktioniert nicht, und ich sehe, dass wir hier "nameFilter" haben, nicht gefunden. Also, lassen Sie uns oben sehen, was wir hier gesagt haben, "name", da haben wir es, wir hatten einen Tippfehler. Suchen Sie das. Lassen Sie uns jetzt sehen, suchen Sie nach dem Namen Glumanda, es funktioniert, "Jar" und ja, großartig. Wenn wir also "A" schreiben, kommt "Atkins", "Electrode" würde "cool", "Poliwag", "Poliwrath", "Bonita" ausführen. Okay, großartig, unser Filter funktioniert.

Dann werden wir "const closeButton = document.querySelector('.search-close-icon')" schreiben, und wir werden das Such-Schließen-Symbol ansprechen, das ist dieses hier. Lassen Sie uns sehen, wir brauchen den Punkt hier drinnen, "search-close-icon". Dann werden wir "closeButton.addEventListener('click', clearSearch)" sagen; wir werden auf einen Klick hören, und wenn wir darauf klicken, werden wir die Suche löschen, das wird eine Funktion sein, die wir noch nicht erstellt haben, und das wird, nun, es wird es eindeutig löschen, unsere Suchfunktion "clearSearch", und wir werden den Wert von "searchInput.value" nehmen und ihn auf einen leeren String setzen. Dann werden wir "displayPokemons(allPokemons)" sagen, denn wenn wir hier klicken, bedeutet das, dass wir nichts filtern wollen, also wollen wir dann einfach alle Pokémon anzeigen. Und dann wollen wir sagen: "notFoundMessage.style.display = 'none'", um die "nicht gefunden"-Nachricht wieder auszublenden. Also, versuchen wir es, nehmen wir die Nummer 22, klicken wir, und es funktioniert. 45, wir klicken auf das Kreuz, es funktioniert. Wie wäre es mit einem Namen, "D", klicken wir, und es funktioniert, gibt uns alle unsere Pokémon in unserer Anzeige hier zurück.

Also, jetzt sind wir bereit, unsere Detailseite tatsächlich zu erstellen. Wie Sie sehen können, haben wir bereits unseren Event-Listener hinzugefügt, lassen Sie uns sehen, "click", der uns tatsächlich zu unserer Detailseite weiterleitet. Wenn Sie also auf ein Pokémon klicken, sehen wir, dass wir eine leere Seite erhalten, und wir sehen hier, dass wir "detail.html" nicht bekommen können, weil, Sie wissen schon, unsere HTML-Seite noch nicht existiert. Also, lassen Sie uns unsere Detailseite erstellen, öffnen Sie unseren Explorer, erstellen Sie eine neue Datei, nennen Sie sie "detail.html", geben Sie ein Ausrufezeichen ein, drücken Sie Enter. Ich werde das "Pokemon Detail" nennen, dann referenzieren wir auf ein...

Skript hier, dem wir die Quelle Punkt Schrägstrich Pokémon Detail Punkt JS geben werden. Lass uns auch diese Datei hier Pokémon Detail.js stattdessen für jetzt erstellen. Lass uns auch das Defer-Attribut hinzufügen. Und innerhalb des Body können wir unser Main mit einer Klasse von Detail Main und dann auch Main schreiben, das sind zwei separate Klassen mit einem Header. Und innerhalb des Headers werden wir eine Klasse von besser haben.

Lass uns auch ein Pokémon anklicken, damit wir die Seite hier sehen können. Wir sehen, wir haben unser Main, wir haben unseren Header, er ist vorerst leer. Innerhalb unseres Headers haben wir ein Div, die Klasse des Header-Wrappers. Innerhalb des Header-Wrappers haben wir ein weiteres Div mit einer Klasse von einem Header Wrap. Und innerhalb des Header Wraps haben wir ein A-Element, das ist ein Link mit Href zu Punkt Schrägstrich, und das bringt uns zur Index.html, das wird unser Zurück-Button und eine Klasse von Back Btn Wrap sein.

[Applaus] Und dann innerhalb des Links werden wir ein Bild mit einer Quelle zu Punkt Schrägstrich Assets hinzufügen, und das wird Back to Home SVG sein, und der Alt-Text wird Back to Home genannt werden. Und wir werden hier auch eine Klasse hinzufügen, nenn sie Back Btn A, sowie eine ID, oh Back to the End. Lass uns auch die Ansicht Zeilenumbruch einschalten.

Also unter dem A-Element werden wir ein weiteres Div mit einer Klasse von Name Wrap hinzufügen, und hierin werden wir H1 hinzufügen, und das wird eine Klasse von Name haben, und wir lassen sie vorerst leer. Wie wir hier sehen können, sollte unser Zurück-Button funktionieren, geh zur Detailseite, wir haben einen weißen Zurück-Button, scrolle zu einem zufälligen Pokémon, und wir haben unseren Zurück-Button hier. Jetzt hier ist, wo wir tatsächlich den Namen jedes Pokémon hinzufügen werden, aber wir lassen ihn im HTML leer, weil wir das mit unserem JavaScript ausfüllen werden.

Dann unter dem zweiten Div hier werden wir ein weiteres Div hinzufügen. [Musik] Und hier werden wir einen Absatz mit einer Klasse von Body Two Fonts hinzufügen. Und dann unter dem Header hier werden wir ein weiteres Div hinzufügen, es ist eine Klasse von Featured Image, hierin ein Link-Element, ich werde hier einfach den Hashtag schreiben, Klasse Arrow Leertaste Left Arrow und ID Left Capital Arrow.

Und innerhalb des Links werden wir ein Bild mit der Quelle Punkt Schrägstrich Asset Chevron Left SVG hinzufügen, und das wird einen Alt-Text von Back Go haben, das ist auch unser Pfeil dort. Dann unter dem A werden wir ein weiteres Div hinzufügen, es wird eine Klasse von Detail Image Wrapper haben, das wird das Bild unseres Pokémon-Bildes sein, das wird leer sein, Alt wird leer sein. Und dann ein weiteres A-Element Hashtag mit einer Klasse von L und dann Right Arrow und dann eine ID von Right Arrow, sowie ein Bild Punkt Schrägstrich Assets Chevron Right, und hier wird es vorwärts sein.

Also haben wir unsere Pfeile hier, und dann sehen wir auf der Detailseite des fertigen Projekts, dass wir sie verwenden, um zwischen unseren Pokémon zu navigieren. Unter unserem Div hier werden wir ein weiteres Div mit einer Klasse von Detail Card Detail Wrapper hinzufügen, hierin ein Div mit einer Klasse von Power Wrapper, und hierin werden wir den Absatz mit einer Klasse von Body Three False Leertaste Type Leertaste Grass hinzufügen, und dann werden wir auch Poison hinzufügen, so.

Und dann unter unserem Div werden wir einen Absatz hinzufügen, er wird eine Klasse über Body Two Fonts About-Text haben, und hierin sind wir About. Und dann unter diesem Absatz ein Div mit einer Klasse von Pokémon Detail Wrapper, hierin ein weiteres Div mit einer Klasse von Pokémon Detail Wrap und wieder eine weitere Klasse Pokémon Detail. Und dann innerhalb des letzten Divs hier werden wir ein Bild hinzufügen, Quelle Punkt Schrägstrich Assets und Weight Punkt SVG, und das wird einen Alt-Text von Weight haben.

Und dann unter dem Bild werden wir einen Absatz mit einer Klasse von Body Three False hinzufügen, und dann Weight Weight so. Und dann unter dem Div ein weiterer Absatz, dieser wird uns eine Klasse von Caption Fonts und Weight geben. Also dann können wir alles innerhalb des Pokémon Detail Wrap nehmen, jetzt können wir es zweimal nach unten kopieren, eins, zwei, Shift Alt Down, weil wir das auch für die Höhe und den Move verwenden werden.

Also für die Höhe werden wir in die Bild-Assets gehen, ich werde Height SVG wählen, ich werde das in Height umbenennen, wir werden das hier auch in Height umbenennen, so, und auch den Text Height. Und dann im Pokémon Detail Wrap haben wir eine Div-Klasse Pokémon Detail, und hier werden wir Move sagen. Wir werden hier kein Bild brauchen, und wir werden auch diese letzte Beschriftung hier nicht brauchen, so.

Und wir werden diesen Absatz nehmen und ihn unter das Pokémon Detail Move Div verschieben, so. Und wir werden sagen, ich werde diesen Absatz in die Caption Fonts umbenennen, und wir werden das Move nennen. Und diese, wie wir hier sehen können, sind die Detailbereiche hier mit dem Gewicht, der Höhe und den Moves hier, und dann die Daten, die tatsächlichen Moves und die Zahlen werden von der Pokémon API ausgefüllt werden.

Dann unter dem zweiten Div hier werden wir einen Absatz mit einer Klasse von Body Three False hinzufügen, sowie Pokémon, lass uns sehen, Pokémon die Beschreibung, und einen weiteren Absatz darunter, Klasse Body Two Fonts About Text, wir werden Basis-Stats sagen. Und hierunter ein weiteres Div mit der Klasse Stats Wrapper und ein Div hierin, Klasse Stats Wrap und auch Data Stat gleich Progress Bar.

Also, was wir hier erstellen, ist dieser Teil. Innerhalb dieses Divs werden wir einen Absatz der Klasse Body Three False und Stats hinzufügen, und es wird hier HP sein. Und dann Absatz Klasse Body Three Fonts und dann leer hier, und dann werden wir Progress sagen, und dann werden wir ein weiteres Element namens Progress hinzufügen, und hier wird der Wert leer sein, und dann wird das Maximum hundert sein, und dann wird die Klasse Progress Bar sein, also das gibt uns eine Progress Bar.

Dann können wir alles vom Stats Wrap dreimal kopieren, eins, zwei, drei, und beim zweiten werden wir es von HP in Attack 80 ATK umbenennen, alles andere können wir gleich lassen, beim dritten werden wir Def für Defense sagen, und dann wird das letzte SATK sein. Und eigentlich müssen wir auch, und lass uns sehen, Data Stat, der Data Stat soll nicht Progress Bar sein, das habe ich falsch geschrieben, es soll hier HP sein, und hier soll es ATK sein, und hier Progress Bar DEF, und dann im letzten wird es Special Attack sein, so.

Jetzt vor unserem Main-Element hier werden wir ein Bild hinzufügen, es wird eine Quelle von Assets Kit Dicks SVG haben, und das wird Alt Pokedex und Klasse Detail EG haben, was dieses Pokedex-Bild hier sein wird. Das ist alles für unser HTML auf unserer Detailseite, hoffentlich haben wir die Dinge richtig geschrieben, aber wenn wir später einen Fehler bekommen, werden wir das einfach beheben, es ist viel Text, also keine Sorge, wir werden das beheben können, auch kannst du in der Beschreibung unten nachsehen, um den Referenzcode zu finden, falls du mit deinem eigenen Code vergleichen möchtest.

Jetzt lass uns unsere Pokémon Details Javascript-Datei öffnen. Das erste, was wir tun werden, ist, wir werden eine Konstante oder Variable erstellen, lass Current Pokémon ID, ich werde das Null nennen, weil es mit nichts beginnt. Und wir werden sagen Document Add Event Listener, wir werden auf das gesamte DOM Content Loaded, im Grunde die Seite, hören, und wir werden sagen, führe dieses Stück Code aus, im Grunde, wenn wir die Seite laden.

Wir werden die Konstante Max Pokémon wieder definieren, wir definieren sie noch einmal, weil dies separate Dateien sind. Und dann Const Pokémon ID New URL Search Params, was eine weitere eingebaute Methode hier ist, und das wird gleich Window Location Search sein, und dann werden wir die ID von dort bekommen, also werden wir hierher gehen und die Nummer eins hier bekommen. Lass uns auch den Zeilenumbruch einschalten.

Dann Const ID ist gleich Parse Int Pokémon ID 10. Was dieses Parse Int tut, ist, es nimmt, was wir hier bekommen, die Pokémon ID, die ein String sein wird, weil alles hier ein String ist, und es wandelt es in eine Ganzzahl oder eine Zahl um, unter Verwendung des 10er-Dezimalsystems, also im Grunde wandeln wir diese ID-Nummer eins hier in eine normale Zahl vom Typ Zahl um.

Dann, wenn ID kleiner als eins ist oder ID größer als Max Pokemons ist, dann geben wir eine Window Location Punkt Href gleich Punkt Schrägstrich und Index.html zurück, im Grunde, wenn die ID kleiner als eins oder größer als 151 ist, kehren wir einfach zur Hauptseite zurück. Dann werden wir sagen Current Pokémon ID gleich ID, und dann werden wir eine Funktion namens Load Pokémon aufrufen, die wir als Nächstes erstellen werden, ID.

Dann lass uns unsere Async-Funktion Load Pokémon erstellen, wo wir die ID des Pokémon als Argument nehmen. Dann werden wir versuchen, danach werden wir einen Fehler abfangen, wenn wir diesen haben, und wenn wir einen Fehler haben, werden wir Install the Error aufrufen und wir werden sagen, und es ist ein Fehler aufgetreten beim Abrufen von Pokémon-Daten, so, und dann werden wir auch Komma Error schreiben, um die Fehlermeldung zu geben, und in diesem Fall werden wir False zurückgeben, und wenn wir nicht False zurückgeben, bedeutet das, dass wir True zurückgeben können, so.

Also jetzt haben wir unsere Syntax bereit für unsere Async-Funktion. Also das erste, was wir tun werden, ist, wir werden die Pokémon- und Speziesdaten abrufen. Lass uns in unsere Pokémon JS-Datei gehen und lass uns Strg F Spezies drücken, und wir werden dieses Ganze einfach so herunterkopieren, und wir werden es hier einfügen.

Also Const Pokémon Species Await Promise All Fetch Pokémon Punkt Code API VG V2 Pokémon ID, dann nehmen wir das Ergebnis, wandeln es in Json um, und wir tun dasselbe für unsere Spezies Pokémon Species. Dann werden wir eine Konstante namens Abilities Wrapper erstellen, die gleich Document Punkt Query Selector sein wird, und wir werden den Pokémon Detail Wrap sowie den Pokémon Detail Move ansprechen, so, und ich werde sagen Abilities Wrapper Punkt Inner HTML ist gleich leerer String, um es zu leeren, die vorherigen Fähigkeiten vom vorherigen Pokémon zu löschen, wenn wir auf einem vorherigen Pokémon waren.

Dann, wenn Current Pokémon ID gleich ID ist, werden wir diese Display Pokémon Details [Musik] aufrufen, was eine Funktion ist, die wir noch nicht erstellt haben, wir werden ihr das Pokémon-Argument geben. Und dann werden wir sagen Const Flavor Text, was der Text sein wird, um das Pokémon zu beschreiben, wir werden einfach englischen Flavor Text bekommen, was eine weitere Funktion ist, die wir noch nicht definiert haben, wir werden Pokémon Species nehmen, ich werde Document Query Selector sagen, und wir werden den Body 3 False Punkt Pokémon Description auswählen, und dann werden wir den Text Text Content ansprechen, ich werde das gleich Flavor Text setzen.

Also eigentlich haben wir hier einen Fehler, das soll hier nicht sein, diese geschweifte Klammer, dasselbe mit der blauen, speichere, da haben wir es, dann gibt uns das den Flavor Text. Dann wollen wir unsere Navigationsbuttons aktualisieren, also Const, wir werden wieder die Destrukturierung verwenden, Left Arrow Right Arrow wird gleich der Destrukturierung wieder Hashtag Left Arrow und Hashtag Right Arrow sein.

Dann werden wir das mappen, wir werden diese Auswahl nehmen, und dann werden wir sagen Document Query Selector die Auswahl, auch werden wir diese geschweiften Klammern hier entfernen, wir brauchen sie nicht, sieh so, da haben wir es. Dann werden wir sagen Left That Row, also Remove Event Listener und Click und dann Navigate [Musik], okay, nun, eine weitere Funktion, die wir noch nicht haben, lass uns das jetzt kopieren und einfügen, Shift Alt Down, und einfach Left Arrow und Start Right Arrow sagen, so, wenn wir auf den linken oder rechten Pfeil klicken, werden wir diese Navigate Pokémon Funktion aufrufen.

Dann, wenn die ID nicht, sieh, nicht eins ist, lass uns Left Arrow und Event Listener drücken, lass mich auf Klick hören, wir werden eine Pfeilfunktion aufrufen, und hier werden wir sagen Navigate Pokémon ID minus eins, also werden wir zur aktuellen ID minus eins gehen. Und dann können wir das herunterkopieren, Shift Alt Down, wenn ID nicht 151 ist, werden wir Right Arrow Event Listener Click Navigate Pokémon ID plus, lass uns sehen, plus eins sehen.

Und dann werden wir das Fenster nehmen, wir werden in die Historie des Fensters gehen, wir werden Push State Building in Build Function aufrufen, und wir werden ihm ein leeres Objekt geben, wir werden ihm einen leeren String geben, und wir werden ihm auch einen Punkt geben, und dann Detail.html Fragezeichen ID gleich und dann Dollar, dann Dollarzeichen geschweifte Klammern ID.

Und was diese Zeile hier tut, ist, dass sie tatsächlich in die Historie des Fensters pusht, sie ändert die URL, ohne die Seite im Grunde neu zu laden, was sehr nützlich ist, wenn wir hier zwischen verschiedenen Pokémon klicken wollen, ohne die Seite tatsächlich neu zu laden, und das nennt man eine Single Page Application, und es ist sehr nützlich für diese Arten von tatsächlichen Anwendungen hier. Also dann haben wir alles, was wir brauchen, in unserer, lass uns sehen, in unserer Load Pokémon Funktion, wenn all dies wahr ist, geben wir das zurück, wenn nicht, fangen wir den Fehler ab und protokollieren ihn.

Dann lass uns eine weitere Async-Funktion erstellen, wir werden Navigate Pokémon sagen, drücke die ID, und wir werden sagen Current Pokémon ID gleich ID, und dann werden wir auf Load Pokémon ID warten. Und dann werden wir hier eine Konstante erstellen, die alle verschiedenen Farben, Typfarben, enthalten wird, es wird ein Objekt sein, und das wird alle Hintergrundfarben und im Grunde alle Typfarben enthalten, die wir hier haben, wir sehen, dass, wenn der Typ Normaltyp hier sich ändert zu, lass uns sehen, es wird Poison oder so, ja, Poison, dann ist es lila, wenn es sich ändert zu, lass uns sehen, Electric, dann ist es gelb, also das sind die Farben, die wir hier definieren werden.

Normal wird gleich Tag A Acht A Acht Sieben Acht sein, also lass uns das herunterkopieren, dann haben wir Fire, das wird Hashtag F Null Acht Drei Null Punkt Null Acht Null Drei Acht Null sein, kopier das herunter, Water wird gleich Sechs Acht Neun Null F ist Null sein, Shift Alt Down, Electric, das wird Hashtag F Acht D Null D Null Drei Null sein, lass mich Grass herunterkopieren, das wird gleich Sieben Acht C Acht Fünf Null sein, kopier und füge es herunter, das nächste wird Ice sein, und das wird Hashtag Neun Acht D Acht E Acht sein, das nächste, ich denke Hashtag C Null Drei Null Zwei Acht, das nächste Poison, das wird A Null Vier Null A Null genannt werden. Sechs Eins Round E Null C Null Sechs Acht, du kannst das auch aus dem Referenzcode kopieren und einfügen, wenn du dich nicht mit dem Tippen all dieses Zeugs herumschlagen willst, Flying wird A Acht Neunzig F Null sein. Psychic, das wird gleich F Acht Fünf Acht Punkt Acht Acht sein, und Bug, das wird gleich A Acht B Acht Zwanzig sein. Dann Rock B Acht A Null Drei Acht, dann Ghost Siebzig Fünf Acht Neun Acht, kleiner Dragon, das wird Siebzig Drei Acht F Acht sein. Dark, drei weitere, Siebzig Fünf Acht Vier Acht, und das vorletzte wird Steel sein, und das wird P Acht P Acht P Null sein, und dann Dark wird E Neun Neun A C sein, da haben wir es, das ist ein Zungenbrecher und ein Tippfehler.

Jetzt können wir unsere Funktion Set Element Styles erstellen, und die wird Elemente nehmen, sie wird CSS-Eigenschaft nehmen, und sie wird einen Wert als unsere Argumente nehmen. Und wir werden sagen Element S For Each, und dann werden wir sagen Element, wir werden Element Style ausführen, und die CSS-Eigenschaft davon, wir werden sagen gleich Wert, also hier fügen wir im Grunde die Elementstile an alle, ähm, alle verschiedenen Elemente hier an, wir werden diese Funktion ziemlich bald verwenden.

Dann werden wir eine weitere Funktion namens RGBA From Hex erstellen, die eine Hex-Farbe nehmen wird, die wir gerade erstellt haben, und du siehst hier, dass wir im Grunde dies ist volle Farbe und dies ist eine etwas durchscheinende Farbe, das ist die RGBA. Und hierin werden wir Parse zurückgeben, und die Hex-Farbe, die wir ihr geben werden, werden wir von der ersten bis zur dritten Stelle slicen, und wir werden ihr eine 16 geben, was uns im Grunde eine etwas durchsichtige Version jeder Farbe geben wird, die wir ihr geben, also werden wir zurückgeben, lass uns sehen, so, Komma, kopier das, füg das dort ein, und füg es noch einmal ein, so, eins zwei drei, dann wird es drei zwei fünf sein, und dann wird es fünf zwei sieben sein, und danach werden wir mit dem Komma verbinden, also hier wandeln wir im Grunde Hex-Farbe in RGBA-Farbe um, indem wir am Ende etwas Durchscheinendes hinzufügen.

Dann werden wir eine weitere Funktion erstellen, wir werden die Höhe und Hintergrund [Musik] Farbe des Pokémon setzen, das wir ihr geben. Es ist eine Const Main Type ist gleich Pokémon Punkt Types und in der Nullten, und dann werden wir den Namen eingeben, dann werden wir die Const Color gleich Type Colors Main Type machen, und dann, wenn es keine Farbe ist, dann Console One und dann Backticks Color Not Defined For Type, und dann werden wir dem einen Hashtag und Main Type geben, also wenn wir die Farbe nicht hinzufügen können, weil wir etwas falsch geschrieben haben, dann werden wir eine Warnung bekommen und wir werden dann zurückkehren.

Dann Const Detail Main Element gleich Document Query Selector, und wir werden das Detail Detail Name ansprechen, dann werden wir Element Styles auf Detail Main Element setzen, und dann werden wir ihm eine Hintergrundfarbe geben, und das wird gleich Color sein. Jetzt lass uns das herunterkopieren, wir werden Element Styles wieder setzen, jetzt wird es Detail Element Main Element Border Color sein, und das wird auch Color genannt werden.

Dann werden wir Element Styles wieder setzen, und wir werden in das Dokument gehen, wir werden Query Selector All dieses Mal sagen, um alle zu nehmen, die die Klasse Power Wrapper größer als P Absätze im Power Wrapper haben, und dann werden wir sagen Back und und wir werden diese Farbe so machen. Lass uns das dreimal herunterkopieren und einfügen, eins zwei drei, das nächste wird einfach nur alte Farbe sein, und das wird, lass uns sehen, Stats Wrapper, eigentlich Wrap und dann P Punkt, also das ist, und dann wird das dritte auch die Farbe sein, und es wird Stats to Wrap sein, und hier wird es Punkt Progress Bar sein.

Dann werden wir sagen Const RGBA Color ist gleich RGBA From Hex Color, und dann Const Style Tag ist gleich Document Punkt Create Element File, und dann Style Tag Inner HTML wird gleich Backticks sein, und dann hierin werden wir unser HTML Punkt Stats Wrap Punkt Progress Bar Doppelpunkt Doppelpunkt Webkit Progress Bar erstellen, und dann die geschweiften Klammern Background Color RGBA Klammern Dollarzeichen geschweifte Klammern RGBA Color mit 0.5 in Opacity, und wir werden das einmal herunterkopieren, also Stats Wrap Progress Bar Webkit Progress, nicht Bar, sondern Value, das wird eine Hintergrundfarbe von einfach Color haben, und nichts danach, so, auch kein RGBA, und lass uns diese Semikolons nicht vergessen, dann danach werden wir sagen Document Head Append Child Style Tag, so.

Dann werden wir eine weitere Funktion erstellen, ich werde Cap B Copy Lies First Letter sagen, was du schon erraten kannst, was es tun wird, es wird eine Zeichenkette nehmen und diese Zeichenkette großschreiben, es wird uns im Grunde alle Pokémon mit dem Großbuchstaben als erstem Zeichen geben, ich werde das Zeichen der Zeichenkette an Position Null, erste Position zwei nach dem Fall nehmen, und dann werden wir String Slice an der ersten Stelle zu Kleinbuchstaben hinzufügen, so dass der Rest des Zeichens wie der Pokémon-Name nach dem ersten großgeschriebenen Buchstaben wieder eingefügt wird.

Dann werden wir eine weitere Funktion namens Display Pokémon Details erstellen, und hier werden wir die Pokémon-Seite nehmen und die Konstanten mit Destrukturierung erstellen, hier werden wir Name ID Types Weight [Musik] Height Abilities und Stats sagen, und es wird gleich Pokémon sein. Dann werden wir das Dokument nehmen, Document Query Selector All, nein, eigentlich nur Query Selector, wir werden den Titel auswählen, wir werden sagen Text Content ist gleich Capitalized First Letter Capitalize About First Letter Pokémon Name, und dann werden wir sagen Calls Capitalized Pokémon Name ist gleich Running Capitalize First Letter auf unserem Namen.

Bevor wir fortfahren, lass uns hier eine weitere Funktion erstellen, wir werden sie Create And Append Element nennen, nimm einen Parent Tag Options, der gleich einem leeren Objekt ist, und dann werden wir Const Element gleich Document Create Element Tag ausführen, und dann werden wir Object Keys alle Optionen ausführen, und dann für jeden Key werden wir Element Key ausführen, und wir werden ihnen einen Options Key Parent und Child Element geben, und dann Element zurückgeben, so.

Wir werden eine weitere Konstante Detail Main Element erstellen, die gleich Document Query Selector Detail Main [Musik] ist. Dann Detail Main Element Class List Punkt und Name und dann zu Kleinbuchstaben. Dann werden wir das Dokument wieder ansprechen, Query Selector, wir werden den Name Wrap Punkt Name Text Content ansprechen, der gleich Capitalized First Capitalized Pokémon Name ist.

Dann werden wir das Dokument eingeben, Query Query Selector, nimm den Pokémon ID Wrap Leertaste Quality Two [Musik] False, und wir werden Text Content ausführen, der gleich Backticks Hashtag Dollarzeichen geschweifte Klammern String ID Punkt Pad ist, wir beginnen bei drei und null, so. Dann werden wir eine neue Konstante erstellen, wir werden Image Element gleich Document Query Selector sagen, und hier werden wir den Detail Image Wrapper Image ansprechen, und dann werden wir sagen Image Element Source ist gleich Backticks Https Doppelpunkt Doppelschrägstrich Raw Punkt Github User Content Punkt Com Get API Schrägstrich Sprites Schrägstrich Master Sprites Other Schrägstrich Green World und dann Schrägstrich All Right D und dann Punkt SCG.

Okay, das wird also unser Hauptbildelement auf der Detailseite sein. Dann eine neue Konstante Type Wrapper gleich Document Query Selector Punkt Power Wrapper, und dann Type Wrapper Punkt Inner HTML gleich leerer String. Dann werden wir die Typen für jeden ansprechen, und dann doppelte Klammern und dann geschweifte Klammern, für jeden Typ werden wir etwas Logik ausführen, wir werden ein Element erstellen und anhängen, Type Wrapper, und dann werden wir dem einen Absatz geben, und dann werde ich dem eine Klasse und einen Namen geben, und das wird Backticks Body Three Fonts und Type und dann Dollarzeichen Type Name sein, und dann Komma Text Content Type Punkt Name Komma.

Dann werden wir das Dokument wieder ansprechen, wir werden Query Selector, wir werden den Poke wieder ansprechen, Detail Wrap sowie das Pokémon Pokémon Detail und die P oder D3 Fonts Punkt Weight, so, und wir können das herunterkopieren und einfügen, es wird Detail Wrap und dann Fonts sein, und statt Weight wird es Height sein, so.

Und dann werden wir das nehmen, wir werden sagen Punkt der Textinhalt davon, Textinhalt ist gleich Backticks Weight, wir hatten definiert, geteilt durch 10. Und dann wird es Kilogramm sein, und in der Bulk API sind aus irgendeinem Grund die Gewichte und Höhen zehnmal so hoch, wie sie sein sollten, also teilen wir es hier einfach durch 10, um Kilogramm und Meter zu erhalten. Also lass uns diesen Teil kopieren und einfügen und hier einfügen, und wir werden hier einfach Height sehen.

Dann werden wir sagen Const Abilities Wrapper gleich Document Query Selector und dann Pokémon Detail Wrap Dark Pokémon Detail Remove, und dann für die Fähigkeiten oder jede Fähigkeit werden wir eine Pfeilfunktion ausführen, ein Element erstellen und anhängen, Abilities Wrapper mit einem Absatz und Plus Name of Body Three und Text Content of Ability [Musik].

Dann werden wir Const Stats Wrapper gleich Document Query Selector Stats Wrapper erstellen, und dann Stats Wrapper Punkt Inner HTML werden wir einfach auf leere Strings setzen. Und dann Const Stat Name Mapping wird gleich Objekt mit HP HP sein, so, kopier das herunter, das wird ATK sein, Defense, das wird DEF sein, äh, lass uns sehen, dieses wird Special Attack in Anführungszeichen sein, weil wir hier sonst keine zwei Wörter verwenden können, und das wird SATK sein, und dann Special Defense Defense und dann Speed.

Dann werden wir die Stats für jeden speichern, ist das, und dann den Base Cut, und wir werden hier eine Pfeilfunktion ausführen, Const Stat Div gleich Document Punkt Create Element Div, und dann Stat Div Punkt Class Name ist gleich Stat Wrap [Musik], und dann Stats Wrapper Punkt Append Child Stat Div, so.

Dann werden wir ein Element an das Stat Div erstellen und anhängen, ich werde dem ein P-Element geben, und wir werden dem den Nachnamen auf den drei falschen Stats geben, sowie einen Textinhalt, der Name Mapping und dann Stat Punkt Name. Lass uns das dreimal herunterkopieren und einfügen, also für das zweite werden wir Elemente erstellen und anhängen, Stat Div Paragraph, und hier wird es Body 3 Fonts ohne die Stats sein, dann wird Text Content String Base Stat sein, das am Anfang drei und das ist null, und dann wird das letzte Stativ sein, und hier wird es Progress sein, und wir werden den Nachnamen haben, der Progress Bar sein wird, Value wird Base Stat sein, und dann Max hier, was hundert sein wird, dann werden wir Type Background Color Pokémon setzen, so.

Bevor wir unsere letzte Funktion hier schreiben, Get English Flavor Text Pokémon Species, und wir sind, sagen wir, eine For-Schleife, Let Entry, ähm, Pokémon Species Flavor, äh, lass uns sehen, Unterstrich Text Unterstrich Entries ist gleich, und dann hierin, wenn Entry Punkt Language Punkt Name gleich English ist, Let Flavor ist gleich Entry Punkt Flavor Unterstrich Text Punkt Replace, und dann werden wir hier zurückkehren, so, und dann hierin werden wir Schrägstrich Rückwärtsschrägstrich If Schrägstrich G Komma schreiben, und dann Leertaste mit einem String darin, Return Labor, und wenn nicht, außerhalb der For-Schleife, werden wir einfach einen leeren String zurückgeben [Musik].

Hier lass uns diese Funktion auch außerhalb der letzten nehmen, sie ist separat, so. Also jetzt bekommen wir hier einen Fehler, ein Fehler ist aufgetreten beim Abrufen von Pokémon-Daten, TypeError, kann Eigenschaften von Null nicht lesen, liest Class List, das ist in Pokémon Detail JS 169 169, lass uns sehen, oder geh Class List und Load Pokémon Detail JS 33 C 33 hier.

Nun, nachdem wir uns das HTML hier angesehen haben, kein Wunder, dass unser JavaScript nicht lädt, das Skript ist nicht im Head, also lass uns das hierher kopieren und einfügen und speichern. Lass uns auch wieder live gehen, sowie wenn wir hier zur Höhe scrollen, sieh SVG Height, da haben wir es, es braucht auch eine Klasse, die wir ihm nicht gegeben haben, Plus of Straight dann, so.

Dann können wir zurück zu unserer Pokémon Details Punkt JS-Datei gehen, und dann, wenn wir hier auf unsere Seite klicken, sehen wir immer noch, dass wir einen Syntaxfehler haben, Pokémon Detail JS 251 Return, das soll hierin sein, so. Also der erste Fehler in unserer Display Pokémon Details Funktion ist, dass wir versuchen, Query Selector auf Detail Main aufzurufen, aber wir haben den Punkt nicht tatsächlich vor Detail Main gesetzt, also das wird dieses Problem lösen, dasselbe im Document Query Selector Name Wrap, wir brauchen hier einen Punkt, und wir sehen, das beginnt unsere Fehler hier zu beheben, lass uns sehen, ob wir weiter nachverfolgen können, ich denke, wir haben einfach vergessen, einige Punkte hinzuzufügen.

Lass uns hier sehen, hier haben wir vergessen, das Bildelement und ALT hinzuzufügen, ich kann ihm tatsächlich die Name-Eigenschaft geben, du hast das, und dann Detail Image Wrapper Image, das sieht korrekt aus, Image Element Source Github Github User Content Punkt Com, lass uns Okay API schreiben, so, das ist nicht, was falsch ist, Sprites Schrägstrich Master Sprites Schrägstrich, äh, uns fehlt hier ein Pokémon Punkt Other Dream World, da haben wir es, wir haben unseren Bisasam, sieh, wenn wir unseren Bisaknosp anklicken, er erscheint, das Gewicht erscheint, wir haben hier weitere Fehler.

Also dann fehlt uns die Hintergrundfarbe, wenn wir zu Zeile 198 gehen, sehen wir, dass dies, glaube ich, auch Punkt Move sein soll, speichere das, 209, wir haben hier einen weiteren Fehler, Stats Wrapper in unserem HTML, uns fehlt hier auch unser Punkt, speichere das, also kommen wir näher, wie wir sehen können, cool.

Und dann werden wir zu 60 gehen, wir haben hier einige Probleme beim Abrufen der Daten, also können wir keine Eigenschaften von Null setzen, setzen Text Content bei Load Pokémon JS 35, also Text Content, das ist dieser Teil, Flavor Text, lass uns sehen, Body Three Fonts Punkt Pokémon, vielleicht so Pokémon, speichere das, und all unsere Fehler sind weg, das war eine gute lange Fehlerbehebung, wir haben unsere Moves, wir haben unseren Flavor Text, wir haben unsere Stats, wir haben alle Elemente, so scheint es jetzt.

Jetzt lass uns unser CSS-Stylesheet importieren, also lass uns unseren Explorer öffnen und unseren Downloads-Ordner wieder öffnen, den wir am Anfang des Tutorials heruntergeladen haben, wir werden den Asset-Ordner nicht hineinziehen, wir werden den Style.css-Ordner hier hineinziehen, und hier setzen wir im Grunde die verschiedenen Body-Schriftarten-Höhen, wir geben Line-Height-Höhen zu den verschiedenen äh Schriftarten, die wir verwenden, wir geben Ränder und und Breiten und Höhen zu verschiedenen Eigenschaften, wir machen hier nicht viel fortgeschrittenes CSS, also kopieren wir das im Grunde einfach hier hinein, bitte schau es dir an, wenn du daran interessiert bist, aber wie am Anfang des Videos erwähnt, konzentrieren wir uns hier auf JavaScript und HTML, und wenn du einen tieferen Blick in CSS werfen möchtest, dann tu das bitte, und du kannst das in der Beschreibung unten finden.

Lass uns unsere Detail.html-Seite unter unserem Titel verlinken, wir werden das Stylesheet hier zu Style.css verlinken, so, und Boom, sieht ziemlich gut aus, uns fehlen hier ein paar Wörter, die wir beheben werden, und wir können sehen, dass wir hier zwischen den Pokémon navigieren können und die Farben sich korrekt ändern, basierend auf dem Typ des Pokémon, cool, sowie der Attacke und den HP etc. etc., cool.

Dann lass uns auch unsere Index.html-Datei mit unserem Stylesheet Style.css verlinken, und wie wir sehen können, haben wir auch unser Styling auf unsere Hauptseite angewendet, cool. Wir haben hier auch einen Unterschied, wie das Layout in der Suche platziert ist, wir werden sehen, ob wir das auch beheben können, volle Breite, wenn ich hier suche, funktioniert es, kann diesen Button auch noch nicht anklicken, also das müssen wir beheben.

Lass uns zurück in die Detailansicht gehen und lass uns hier inspizieren, und wir können sehen, dass wir Stats Wrap oben hier haben, wir haben Attack, während hier uns fehlt, wir haben Paragraph Paragraph Progress, hier haben wir nur Paragraph, aber es ist leer, wenn wir zu unseren Pokémon Details gehen und zum Const Stat Name Mapping gehen, lass uns überprüfen, ob wir hier etwas falsch geschrieben haben, eine Defense, lass uns das in S ändern, sieh, was passiert, S, und das lässt es erscheinen, weil wir hier unterschiedliche ähm Benennungen verwendet haben, lass uns das suchen und das in S ändern und speichern, und das lässt sie erscheinen, denn wenn wir diese Special Defense googeln, kopier das, lass uns zur Poke API gehen, lass uns einfach die Copy API Special Defense anklicken, wir sehen, dass es mit Rand der verschiedenen Wörter auf verschiedene Arten der Schreibweise geschrieben ist, amerikanisch versus britisch, also das behebt das.

Unsere Detailseite sieht fantastisch aus, wir wechseln zwischen unseren Pokémon, unsere Farben wechseln und alle Kräfte, Gewicht, hier sehen wir, Gewicht ist Kilo, Höhe ist auch in Kilo, also lass uns einfach nach dieser Höhe suchen und wir werden das in Meter ändern, so, dass direkt nebeneinander, so, ist das, wie wir das in der Endversion gemacht haben, ja, haben wir, okay, die Moves sind korrekt, der Text wird genau geändert.

Lass uns zurück zu unserer Hauptseite gehen, um zu sehen, ob wir diese Suchleiste hier beheben können, um das zu inspizieren, um zu sehen, ob uns hier in unserem HTML etwas fehlt, also lass uns einfach Search Search Wrap suchen [Musik]. Also wir haben unseren Search Wrapper Search Icon, es ist ein aussehendes C, das wäre das Search Wrapper Auge, es scheint, als ob der Container hier, wenn wir hier Header Container sehen, er nimmt hundert Prozent der Breite ein, lass uns sehen, wie es in unserem Projekt aussieht, Container hundert Prozent der Breite, hmm, Header Home, hat das dann eine Breite im fertigen Projekt, Header Home hat eine Breite von neunzig Prozent, also fehlt uns das, hatte unser Home, ah, es ist Header und ohne den Bindestrich Home, also lass uns zu unserem, lass uns sehen, HTML Header Home gehen, wir sehen es hier, und lass uns den Bindestrich entfernen, speichern, und das behebt unser Breitenproblem hier.

Jetzt, wenn wir ein Pokémon schreiben, Pokémon nicht gefunden, natürlich sind wir bei den Zahlen 43. Jetzt der letzte Teil dieses Projekts, wir müssen hier die Suchfunktionalität hinzufügen, im Grunde, um dies aufpoppen zu lassen, wenn wir diesen Button klicken, wie es im fertigen Projekt hier der Fall ist, damit wir tatsächlich ändern können, wonach wir suchen, schließe die API vorerst.

Lass uns eine neue Datei erstellen und sie Search Punkt JS nennen, und in der Index-Datei werden wir auch darauf verweisen, also werden wir sagen Script, es wird Source sein, es wird Punkt Schrägstrich Search.js sein, und auch ein Defer hier, schließe das, du kannst die anderen Dateien hier schließen und Push Search öffnen, so.

Dann werden wir eine Konstante Input Element erstellen, es wird gleich Document Query Selector sein, und es wird Hashtag Search Input sein, Zeilenumbruch das, und dann werden wir das zweimal herunterkopieren und einfügen, und es wird Search Icon Unterstrich Icon sein, und das wird Search Close Icon sein, und dann wird das dritte Sort Wrapper sein, mit dem Ansprechen nicht des Hashtags, sondern des Punkt Sort Wrapper.

Dann werden wir Event Listener zu diesen hinzufügen, Input Element Punkt Add Event Listener Input, und dann, wenn wir ihm einen Input geben, werden wir äh Code hier ausführen, der die Handle Input Change Funktion aufrufen wird, die wir noch nicht definiert haben, und sie wird Input Element als Argument nehmen. Dann können wir das zweimal herunterkopieren, Search Icon Add In Add Event Listener, und hier werden wir klicken, und dann werden wir Handle Search, lass uns sehen, Handle Search Close On Click, was eine weitere Funktion sein wird, und dann Sort Wrapper Add Event Listener Click, und wir werden Handle Sort Icon All Click.

Also dann die erste Funktion, die wir erstellen werden, Handle Input Change, sie wird Input Element nehmen, und dann kannst du keine Const Input Value definieren, das Input Element Punkt Value, dann, wenn Input Value nicht gleich leerer String ist, Query Selector Search Close Icon und Oops Punkt Class List Punkt Add Search Close Icon Invisible, so, diese zielen im Grunde darauf ab, ob es sichtbar ist oder nicht, sonst Document, und dann lass uns einfach diesen Query Selector Search Close Icon Class List Remove Search Close Icon Visible kopieren und einfügen.

Dann die nächste Funktion Handle Search Close On Click, und dort werden wir Document ansprechen, wir werden einfach kopieren und einfügen, wir werden Query Selector Search Hashtag Search Input Punkt Value gleich leere Strings, dann Document Query Selector Hashtag Search Close Icon Punkt Class List Remove Search Close Icon Visible.

Und dann lass uns diese Funktion herunterkopieren, Handle Sort Icon On Clicked, wir werden Document ansprechen, wir werden Query Selector sagen, und wir werden Filter Wrapped Wrapper nehmen, wir werden Class List Toggle sagen, das wird Filter Wrapper Open [Musik] sein, und dann zuletzt werden wir sagen Document Query Selector Body Class List Punkt Toggle Filter [Musik] Overlay.

Lass uns sehen, ob es funktioniert, öffne unsere Konsole, wir drücken 42, lass uns sehen, 23, wir kommen dorthin, hier kommen wir dorthin, wie wir sehen können, Search JS 21 oder 6 Handle Input Change, der erste Fehler hier, den wir zwischen Zeile 5 und 13 haben. Search Icon und Search Sort Wrapper brauchen hier keine Funktion, also können wir diesen Teil einfach so entfernen, und dasselbe hier, so, und dann sollte uns das ermöglichen, die Sortiernummer hier anzuklicken, also wenn du eins schreibst und dann Namen schreiben, können wir die Namen jetzt schreiben, also das funktioniert, wir bekommen immer noch Fehler, kann Eigenschaften von Null nicht lesen, liest Class List und Add Handle Input Change Const Input Value Input Element Punkt Value Class List, hier fehlt uns Hashtag, dasselbe hier, Hashtag, und jetzt, wenn wir suchen, geben wir den Fehler nicht aus, wir können zu Name Search Char gehen, zu Glurak gehen, zu Schiggy, Schillok, Turtok, Raupy, okay, dann haben wir den Rest unserer Funktionalität, lass uns das so im Vollbildmodus machen, lass uns sehen, sieht gut aus, wenn wir die Größe hier ändern, sieht immer noch gut aus, großartig.

Okay, wir haben unseren Pokédex fertiggestellt, lass uns die Hauptseite sehen, wir machen sie breiter, es funktioniert, wir können scrollen, wir können auf das Pokémon klicken, wir können die Details bekommen, aber es gibt hier ein Problem mit dem Hintergrund, lass uns HTML sehen, das ist der Body, lass uns sehen, ob wir dem jetzt eine Höhe geben, wir haben bereits eine Höhe, lass uns Main sehen, wir können gehen und unser HTML, unser Style.css öffnen, und lass uns sehen, wir hatten, lass uns das hier wieder auskommentieren, sieh, was das tut, oh, wir haben unseren Body, wir haben unser Main, es ist der Name, den wir strecken wollen, Main Right [Musik] Next Content, da haben wir es, im letzten Abschnitt hier in Detail Main Main, werden wir eine Höhe von Max Content geben, lass uns sehen, ob das es behebt, lass uns zurück zu unserer Hauptseite gehen, streckt hier nichts wirklich, lass es uns im Vollbildmodus machen, rechts, und das schließen, und dann, wenn wir zu einem anderen gehen, ja, wir haben die Hintergrundfarbe auf der ganzen Seite, großartig, ich hoffe, du hast dieses Tutorial genossen, ich hoffe, du hast es genossen, diese Pokédex zu erstellen und ein bisschen über die APIs zu lernen, äh, wir waren etwas schnell mit dem JavaScript, ich weiß das, es tut mir leid, bitte lass es mich in den Kommentaren wissen, wenn es einen Teil gab, den du besser erklärt haben möchtest, oder eine Methode, eine eingebaute Methode, die du etwas mehr erklärt haben möchtest, ähm, ansonsten lass es mich bitte in den Kommentaren wissen, welches Video du in Zukunft sehen möchtest, und ich, wenn dir dieses Video gefällt, wird dir dieses andere Video gefallen, das hier vorgeschlagen wird, bis zum nächsten Mal, tschüss.