Heim >Web-Frontend >js-Tutorial >Responsives JavaScript-Karussell für stündliche API-Daten

Responsives JavaScript-Karussell für stündliche API-Daten

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-10-21 14:42:30787Durchsuche

Responsive JavaScript Carousel for API Hourly Data

Ich hätte eine unvollständige Lösung fast mit einer fertigen Lösung verwechselt und mich an die Arbeit an anderen Teilen meiner Wetter-App gemacht! Während ich an dem Karussell arbeitete, das 12 Stunden Wetter anzeigen sollte, wollte ich die Funktion hinzufügen, die beim Abrufen der Stunden des nächsten Tages helfen würde, falls der aktuelle Tag zu Ende wäre. Anstatt jedoch zum nächsten Tag zu wechseln, kehrte das Karussell immer wieder zum Beginn der Stunden des aktuellen Tages zurück, und ich dachte fälschlicherweise, die Aufgabe sei erledigt. Huch!

Erste Herausforderungen

Ich habe über zwei „for-Schleifen“ nachgedacht, aber ich glaube nicht, dass es richtig war, dass „j“ alle seine Elemente über die Länge des gesamten „i“ ausgibt. Ich habe online viele Blogs über die Verwendung des Moduloperators für „zirkuläre Arrays“ gefunden, wusste aber nicht, wie das in meinem Fall helfen würde. Ich musste die Stunden des aktuellen Tages durchgehen und dann zum nächsten Tag wechseln, sobald die Stunden auf Null zurückgesetzt wurden. Es passierte viel und ich musste es prägnanter gestalten und alles in einer Funktion unterbringen. Hart!

Unvollständige Lösungen und Fehler erkennen

Ich habe allerdings online etwas wirklich Cooles gefunden, das möglicherweise ein großes Problem für mich löst. Es hat mir geholfen zu verstehen, wie der Moduloperator für kreisförmige Arrays funktioniert. Hier ist das Beispiel auf der Website:

const daysOfWeek = [
  "Monday",
  "Tuesday",
  "Wednesday",
  "Thursday",
  "Friday",
  "Saturday",
  "Sunday",
];
// Function to cycle through the days of the week
function cycleDays(index) {
  return daysOfWeek[index % daysOfWeek.length];
}
// Let's cycle through the days:
for (let i = 0; i < 10; i++) {
  console.log(`Day ${i + 1}: ${cycleDays(i)}`);
}

Das Ergebnis ist wie folgt:
Tag 1: Montag
Tag 2: Dienstag
...

Was ich wollte war, anstatt zum Array daysOfWeek zurückzukehren und bei „Montag“ zu beginnen, sollte es zu einem völlig anderen Array gehen. Also habe ich den Code zum Code-Editor gebracht und ihn ein wenig geändert. Zuerst habe ich eine Variable namens ‘currentIndex’ erstellt und die Modulus-Operation darin gespeichert. Dann habe ich es an der Konsole angemeldet. Es wurde nach 6 zurückgesetzt und wurde wieder Null.

Allerdings habe ich die falsche Variable in der Konsole protokolliert. Denn wenn ich die if-Bedingung so schreiben würde: if(currentIndex === 0), würde sie sich tatsächlich direkt am Anfang der Schleife in Richtung eines neuen Arrays bewegen. Jetzt habe ich stattdessen den „Index“ protokolliert und endlich die Antwort gefunden! Um den neuen Code zu testen, habe ich ein neues Array für „Monate“ erstellt und dann versucht, den Wechsel vorzunehmen. Aber ich habe einen weiteren Fehler gemacht – lassen Sie mich Ihnen zeigen:

const daysOfWeek = [
  "Monday",
  "Tuesday",
  "Wednesday",
  "Thursday",
  "Friday",
  "Saturday",
  "Sunday",
];
const months = [
  'Jan',
  'Feb',
  'March'
];
// Function to cycle through the days of the week
function cycleDays(index) {
  let currentIndex = index % daysOfWeek.length
  console.log(index)
 if(index === 7){
   return months[currentIndex]
 } else {
     return daysOfWeek[currentIndex];
 }
}
// Let's cycle through the days:
for (let i = 0; i < 10; i++) {
  console.log(`Day ${i + 1}: ${cycleDays(i)}`);
}

Nach der Protokollierung von „Jan“ wurde wieder auf das ursprüngliche Array umgeschaltet. Der Fehler war eine strikte Gleichheitsprüfung, ich hätte stattdessen „größer als oder gleich“ verwenden sollen. Als ich das angeschlossen habe, wurde erfolgreich auf das neue Array umgeschaltet!

Jetzt wollte ich, dass die Schleife bei der aktuellen Stunde beginnt und ohne Unterbrechung weiterläuft, mit einer Markierung an der richtigen Stelle, um zwischen den Arrays zu wechseln. Dieser Marker ist der Moduloperator und nicht die Länge des Arrays. Ich könnte auch die Länge des Arrays verwenden, die in diesem Fall 24 beträgt, aber ich bleibe vorerst beim hartcodierten Wert von 24.

currentIndex = (currentIndex 1) % 9

Diese Zeile ermöglicht es mir, während der Schleife vom ersten zum zweiten Tag zu wechseln, ohne sie anzuhalten. Hier ist ein weiterer Test (ich habe die Arrays so aktualisiert, dass sie den API-Ergebnissen ähneln):

const daysOfWeek = [
  "Monday",
  "Tuesday",
  "Wednesday",
  "Thursday",
  "Friday",
  "Saturday",
  "Sunday",
];
// Function to cycle through the days of the week
function cycleDays(index) {
  return daysOfWeek[index % daysOfWeek.length];
}
// Let's cycle through the days:
for (let i = 0; i < 10; i++) {
  console.log(`Day ${i + 1}: ${cycleDays(i)}`);
}

Beachten Sie etwas Interessantes in den Ergebnissen:

Index ist 5 und Montag ist sechs und i ist 0
Index ist 6 und Montag ist sieben und i ist 1
Index ist 7 und Montag ist acht und i ist 2
Index ist 8 und Montag ist neun und i ist 3
Index ist 9 und Montag ist zehn und i ist 4
index ist 0 und Montag ist eins und i ist 5
Index ist 0 und Dienstag ist 11
Index ist 1 und Montag ist 12 und i ist 6
Index ist 2 und Montag ist 13 und i ist 7
Index ist 3 und Montag ist 14 und i ist 8
Index ist 4 und Montag ist ¬15 und i ist 9

Das Problem hierbei ist, dass die Schleife einmal von Anfang an ausgeführt wird und wenn sie die Bedingung (if(currentIndex === 0)) erreicht, wechselt sie das Array. Wenn jedoch currentIndex = 0 (d. h. 10 % 10 = 0), wird auf hours[currentIndex] zugegriffen, bevor die if-Bedingung ausgeführt wird. Deshalb sehen Sie auch nach der Umstellung Werte von dayOne (z. B. „eins“).

Um dies zu beheben, muss die if-Bedingung überprüft werden, direkt nachdem currentIndex 0 wird, damit der Array-Wechsel vor der Protokollierung erfolgt:

console.log(index ist ${currentIndex} und Montag ist ${hours[currentIndex]} und i ist ${i})...

Durch Ändern der Position der Bedingung kann sichergestellt werden, dass der Wechsel zum richtigen Zeitpunkt erfolgt, ohne dass zuerst auf das falsche Array zugegriffen wird.

const daysOfWeek = [
  "Monday",
  "Tuesday",
  "Wednesday",
  "Thursday",
  "Friday",
  "Saturday",
  "Sunday",
];
const months = [
  'Jan',
  'Feb',
  'March'
];
// Function to cycle through the days of the week
function cycleDays(index) {
  let currentIndex = index % daysOfWeek.length
  console.log(index)
 if(index === 7){
   return months[currentIndex]
 } else {
     return daysOfWeek[currentIndex];
 }
}
// Let's cycle through the days:
for (let i = 0; i < 10; i++) {
  console.log(`Day ${i + 1}: ${cycleDays(i)}`);
}

Mein Code ist fast fertig. Der einzige Fehler, den ich hier mache, ist die Protokollierung von „Montag“ statt „Dienstag“. Die Werte stammen zwar aus dem Array ‘Tuesday’, aber aufgrund der falschen Schreibweise der console.log-Anweisung wird immer wieder ‘Monday’ angezeigt. Ich schätze, es ist ziemlich schwierig, zwei und zwei zusammenzuzählen und die Bildprotokollierung im Vergleich dazu, tatsächlich Werte in HTML-Elemente einzugeben. Hier ist eine kleine Verbesserung mit dem ternären Operator (ja, ich habe wieder die Elemente des Arrays vertauscht!):

const dayOne = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'];
const dayTwo = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
let hours = dayOne;
let currentHour = 5;
function cycleDays(currentHour) {
  let currentIndex = currentHour
  for (let i = 0; i < 10; i++) {
    console.log(`index is ${currentIndex} and dayOne is ${hours[currentIndex]}`)
    if(currentIndex === 0){
      hours = dayTwo
    console.log(`index is ${currentIndex} and dayTwo is ${hours[currentIndex]}`)
    } 
  currentIndex = (currentIndex + 1) % 9

} 
}
cycleDays(currentHour)

Endlich kann ich meinen Code für die 3-Tage-Daten erstellen, die ich von der API abrufe. Hier ist die verfeinerte Version:

const daysOfWeek = [
  "Monday",
  "Tuesday",
  "Wednesday",
  "Thursday",
  "Friday",
  "Saturday",
  "Sunday",
];
// Function to cycle through the days of the week
function cycleDays(index) {
  return daysOfWeek[index % daysOfWeek.length];
}
// Let's cycle through the days:
for (let i = 0; i < 10; i++) {
  console.log(`Day ${i + 1}: ${cycleDays(i)}`);
}

Erstellen dynamischer HTML-Elemente

Lassen Sie uns über die Generierung der 12 Divs sprechen. Ich konnte mir nicht vorstellen, wie ich die Knöpfe auf beiden Seiten des übergeordneten Divs hinbekomme, während die 12 Stunden einfach dazwischen schweben. Wenn ich die 12 Divs im selben übergeordneten Element wie die Schaltflächen generieren würde, bräuchten die Schaltflächenelemente eine andere Ausrichtungseinstellung als die 12 Divs.

Es machte nur Sinn, ihnen einen eigenen Container zu geben. Es hat eine Weile gedauert, bis ich das herausgefunden habe – ich musste tatsächlich darüber schlafen. Dann habe ich am nächsten Tag .btn-container eingegeben und die Tabulatortaste gedrückt, und von da an hat alles geklickt. Ich hatte in den Tutorials von John Smilga jedes gruppierte Element und seine eigenen Container in übergeordneten Containern gesehen. Ich wusste nicht, warum eine solche Gruppierung notwendig sein würde, bis ich mit dem Entwurf des 24-Stunden-Containers begann. Es war ein echter „Gotcha-Moment“.

Jetzt kam ein weiteres Problem, das tagelang anhielt. Der Slider, den ich in den Tutorials entworfen habe, war nicht so anspruchsvoll wie diese Divs. In den Tutorials gab es einen einfachen Übersetzungswert, aber im Moment habe ich einige Probleme. Auf kleineren Bildschirmen klebten die Divs zusammen und begannen, wie Spaghetti auszusehen.

Und als ich eine einfache TranslateX-Eigenschaft verwendete, d. h. als ich die Pixel „erraten“ habe, blieb viel Platz übrig, nachdem die Divs vollständig nach links verschoben worden waren. Das bedeutete, dass sie mehr als ihre Gesamtbreite übersetzten. Ich musste einen geeigneten Wert finden, um sicherzustellen, dass die Divs genau am Ende endeten, ohne zusätzlichen Platz zu lassen. Nach langer Suche bin ich auf einen Blog gestoßen, der verschiedene Lösungen anbietet.

Es gab viele Lösungen. Einige von ihnen verwendeten den Modulo-Operator, was mich an die kreisförmige Array-Logik erinnerte, die ich beim Wechseln der Tage in der „for-Schleife“ angewendet hatte. Hier gab es viele Kommentare, die Math.min und Math.max verwendeten. Dies würde im Grunde dazu führen, dass sich der Container verschiebt, bis das Ende seiner Länge erreicht ist. Exzellent! Also kein Leerraum mehr? Nicht so schnell...

Ein Unterschied zu diesen Beispielen bestand darin, dass mein Container zunächst 3 oder 4 Divs anzeigte. Wenn der Offset also 0 ist, ist im übergeordneten Container bereits eine bestimmte Länge vorhanden.

Sie zeigten das Bild an, indem sie die Zahl 1 hinzufügten. Ihr Karussell schob also entsprechend der Indexnummer der Bilder im Array ein Bild nach vorne. Wenn sich beispielsweise 10 Bilder in einem Container befinden und wir eines zur Variablen currentImage hinzufügen, ist der von Math.min berechnete Wert „1“. Wenn wir dann eine weitere „1“ hinzufügen, ist das aktuelle Bild 2 und der Wert ist 2 von Math.min, weil 2 mod 10 2 ist. Dieses spezielle Beispiel würde das Spiel des Schiebereglers ändern Ich versuche es zu machen. Das war der Code, der mir ins Auge fiel:

const daysOfWeek = [
  "Monday",
  "Tuesday",
  "Wednesday",
  "Thursday",
  "Friday",
  "Saturday",
  "Sunday",
];
// Function to cycle through the days of the week
function cycleDays(index) {
  return daysOfWeek[index % daysOfWeek.length];
}
// Let's cycle through the days:
for (let i = 0; i < 10; i++) {
  console.log(`Day ${i + 1}: ${cycleDays(i)}`);
}

Die Brillanz hinter Richard Kichenamas Lösung, die in den Kommentaren zu finden ist, liegt in der Verwendung von Math.max, um sicherzustellen, dass der Wert nicht unter 0 fällt, und Math.min, um den Übersetzungswert zu berechnen, bis er die maximale Länge erreicht Bildarray.

Wie sollte ich nun das Problem des Leerraums lösen? Ich musste die Ränder aller untergeordneten Divs berücksichtigen und sie addieren, um die Gesamtlänge der untergeordneten Divs zu erhalten. Dann sollte der Schieber aufhören, sich zu bewegen, sobald das letzte Kind erreicht ist. Das bedeutet, dass die Gesamtbreite die Summe aller Breiten der untergeordneten Elemente plus deren Ränder ist.

Allerdings stieß ich auf ein anderes Problem: Einige der Divs wurden bereits im Container angezeigt, was mich wieder stecken ließ. Zum Glück kam mir ein Freund zu Hilfe. Nachdem ich das Problem mit ihnen besprochen habe, habe ich Folgendes verstanden:

Ich konnte nicht die gesamte Länge der Kinderdivs berücksichtigen. Es blieb fast so viel Leerraum übrig, wie der Container lang war. Die Lösung bestand darin, die Länge des übergeordneten Containers von der Gesamtlänge der untergeordneten Container (einschließlich Rändern) abzuziehen. Diese Anpassung hat dazu beigetragen, das Leerraumproblem zu lösen – puh!

Einige der Codebeispiele hatten eine Variable, die so etwas wie ein „Zähler“ war. Es fungierte als „Zähler“ für die Übersetzungseigenschaft. Wenn diese Variable zunahm, nahm auch die Übersetzungseigenschaft zu und so weiter. Ich habe die Eigenschaften Math.min und Math.max für die Schaltflächen „Weiter“ und „Zurück“ getrennt. Auf diese Weise war es hilfreicher und einfacher.

In den Beispielen, auf die ich verwiesen habe, verwendete der Code die Länge des Arrays, um den Folienabstand zu bestimmen, aber wie in meiner vorherigen Diskussion mit meinem Freund musste ich den Leerraum berücksichtigen, also musste ich die Länge von subtrahieren Der Behälter. Auf diese Weise habe ich sichergestellt, dass sich meine Divs nur um einen bestimmten Betrag bewegen konnten, und so den zusätzlichen Platz am Ende vermieden.

Außerdem habe ich dank der Tutorials von John Smilga gelernt, wie man die Breite, Höhe und oberen Eigenschaften von Elementen ermittelt. Es war ein Kampf, den richtigen Wert anzuwenden, und es war auch ein Kampf herauszufinden, dass einige der Werte Zeichenfolgen sind und in Zahlen umgewandelt werden müssen. Ich habe das leicht bei Google gefunden und bin auf ‘parseFloat’ aufmerksam geworden.

Ich bin auch auf eine weitere hilfreiche Ressource gestoßen, die mir beigebracht hat, wie man nur drei Divs für große Bildschirme und zwei Divs für kleine Bildschirme anzeigt. Der Trick bestand darin, 100 % der Containerbreite durch 3 (oder 2 bei kleinen Bildschirmen) zu dividieren und die Ränder abzuziehen. Dies ermöglichte gleich große Divs, die perfekt in den Container passen (so clever!). Um sich schließlich die endgültige Funktion anzusehen, besuchen Sie bitte meinen GitHub. Hier ist der Link zu meinem Repository.

Der Fenster-Ereignis-Listener für die Größenänderung war entscheidend für die Behebung der Ausrichtungsprobleme in meinem Container. Das Problem „Flash of Unstyled Content“ (FOUC) wurde behoben, indem der Offset bei der Größenänderung zurückgesetzt wurde. Ich muss meinem Freund dafür danken, dass er mir geholfen hat zu verstehen, wie man maxOffset berechnet – das hat das Spiel wirklich verändert.

Abschließend noch ein Dankeschön an alle erfahrenen Entwickler: Jedes Wort, das Sie teilen, hilft jemandem, der neu auf dem Gebiet ist. Veröffentlichen Sie also weiterhin die Informationen von Ihrer Seite, während wir auf der anderen Seite gespannt darauf warten, zu lernen. Danke schön!

Das obige ist der detaillierte Inhalt vonResponsives JavaScript-Karussell für stündliche API-Daten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn