ホームページ  >  記事  >  ウェブフロントエンド  >  API 時間別データの応答性の高い JavaScript カルーセル

API 時間別データの応答性の高い JavaScript カルーセル

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-10-21 14:42:30714ブラウズ

Responsive JavaScript Carousel for API Hourly Data

不完全なソリューションを完成したソリューションと間違えそうになり、天気予報アプリの他の部分の作業に移りました。 12 時間の天気を表示するカルーセルの作業中に、その日が終了した場合に次の日の時間を取得するのに役立つ機能を追加したいと思いました。しかし、カルーセルは翌日に移行するのではなく、その日の時間の最初にループバックし続けたため、タスクが完了したと誤って思いました。やったー!

初期の課題

2 つの「for ループ」について考えましたが、「i」全体の長さに対してすべての要素を出力する「j」は正しくなかったと思います。 「円形配列」に対するモジュラス演算子の使用については、オンラインでたくさんのブログを見つけましたが、それが私の場合にどのように役立つかわかりませんでした。現在の時間をループし、時間がゼロにリセットされたら翌日に切り替える必要がありました。多くのことが起こっていたため、より簡潔にしてすべてを 1 つの関数にまとめる必要がありました。厳しい!

不完全な解決策と間違いを認識する

オンラインで本当に素晴らしいものを見つけました。それは私にとって大きな問題を解決してくれるかもしれません。これは、円形配列に対してモジュラス演算子がどのように機能するかを理解するのに役立ちました。ウェブサイト上の例は次のとおりです:

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)}`);
}

結果は次のようになります:
1日目: 月曜日
2日目: 火曜日
...

私が望んでいたのは、daysOfWeek 配列に戻って ‘Monday’ から開始するのではなく、完全に異なる配列に移動することです。そこで、コードをコードエディターに取り込み、少し変更しました。まず、‘currentIndex’という変数を作成し、そこにモジュラス演算を保存しました。次に、それをコンソールに記録しました。 6後にリセットされ、再びゼロになりました。

しかし、私は間違った変数をコンソールに記録していました。なぜなら、if 条件を if(currentIndex === 0) のように書いた場合、実際にはループの先頭で新しい配列に向かって移動することになるからです。そこで、代わりに「インデックス」を記録したところ、ついに答えが見つかりました。新しいコードをテストするために、'months' の新しい配列を作成し、切り替えを試みました。しかし、私は別の間違いを犯しました。お見せしましょう:

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)}`);
}

「Jan」をログに記録した後、元の配列に戻りました。間違いは厳密な等価性チェックでした。代わりに 「以上」 を使用すべきでした。それを接続すると、新しいアレイに正常に切り替わりました!

ここで、ループを現在の時間から開始し、配列間を切り替えるためのマーカーを配置して、停止せずに継続するようにしたいと考えました。そのマーカーは、配列の長さではなくモジュラス演算子になります。配列の長さを使用することもできます。この場合は 24 ですが、今のところはハードコードされた値 24 にこだわります。

currentIndex = (currentIndex 1) % 9

この行により、ループ中に停止せずに 1 日目から 2 日目に切り替えることができます。これは別のトライアルです (API の結果に似せるために配列を更新しました):

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)}`);
}

結果で興味深い点に注目してください:

インデックスは 5、月曜日は 6、i は 0
インデックスは 6、月曜日は 7、i は 1
インデックスは 7、月曜日は 8、i は 2
インデックスは 8、月曜日は 9、i は 3
インデックスは 9、月曜日は 10、私は 4
インデックスは 0、月曜日は 1、i は 5
インデックスは 0、火曜日は 11 です
インデックスは 1、月曜日は 12、i は 6
インデックスは 2、月曜日は 13、i は 7
インデックスは 3、月曜日は 14、i は 8
インデックスは 4、月曜日は з15、i は 9

ここでの問題は、ループが最初から 1 回実行され、(if(currentIndex === 0)) の条件に達すると、配列が切り替わることです。ただし、currentIndex = 0 (つまり、10 % 10 = 0) の場合、if 条件が実行される前に hours[currentIndex] がアクセスされます。そのため、切り替え後も dayOne の値 (「one」など) が表示されます。

これを修正するには、currentIndex が 0 になった直後に if 条件をチェックし、ロギングの前に配列の切り替えが行われるようにする必要があります。

console.log(インデックスは ${currentIndex}、月曜日は ${hours[currentIndex]}、i は ${i})...

条件の位置を変更することで、最初に間違った配列にアクセスすることなく、確実に正しいタイミングで切り替えが行われるようにすることができます。

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)}`);
}

私のコードはもうすぐ完成します。ここで私が犯している唯一の間違いは、「火曜日」 ではなく 「月曜日」 と記録していることです。ただし、値は ‘Monday’ 配列からのものですが、console.log ステートメントの記述方法が間違っているため、‘Monday’ と表示され続けます。おそらく、2 つと 2 つを組み合わせてログを作成し、実際に HTML 要素に値を入力するのはかなり難しいと思います。ここでは、三項演算子を使用して少し改善しました (はい、配列の要素を再度切り替えました!):

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)

最後に、API から取得している 3 日分のデータのコードを構築できます。洗練されたバージョンは次のとおりです。

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)}`);
}

動的HTML要素の作成

12 個の div の生成について話しましょう。親 div の両側にあるボタンを取得する方法がわかりませんでしたが、その間に 12 時間が表示されます。ボタンと同じ親に 12 個の div を生成する場合、ボタン要素には 12 個の div とは異なる位置揃え設定が必要になります。

彼らに専用の容器を持たせるのは当然のことです。これを理解するまでには時間がかかりました。実際に寝なければなりませんでした。そして翌日、.btn-container と入力してタブを押すと、そこからすべてがクリックされました。 John Smilga のチュートリアルで、グループ化されたすべてのアイテムと親コンテナー内の独自のコンテナーを見てきましたが、24 時間コンテナーの設計を始めるまで、なぜそのようなグループ化が必要なのかわかりませんでした。それはまさに「ガッチャな瞬間」でした。

ここで、何日も続く別の問題が発生しました。チュートリアルで私が設計したスライダーは、これらの div ほど難しくはありませんでした。チュートリアルには単純な値の変換がありましたが、現時点ではかなりの問題があります。小さな画面では、div がくっついてスパゲッティのように見え始めていました。

そして、単純な translationX プロパティを使用したとき、つまりピクセルを「推測」したとき、div が完全に左に移動した後に多くのスペースが残りました。これは、合計した幅を超えて翻訳していることを意味します。余分なスペースを残さずに div が最後に正確に停止するように、適切な値を見つける必要がありました。長い間検索した結果、さまざまな解決策を提供するブログを見つけました。

解決策はたくさんありました。そのうちのいくつかはモジュロ演算子を使用していました。これは、「for ループ」で日を切り替えるときに適用した循環配列ロジックを思い出させました。 Math.minMath.max を使用するコメントがここにたくさんありました。これは基本的に、長さの終わりに達するまでコンテナを平行移動させます。素晴らしい!では、空白はもう必要ないのでしょうか? それほど速くはありません...

これらの例と異なる点の 1 つは、私のコンテナーには最初に 3 つまたは 4 つの div が表示されるということでした。したがって、オフセットが 0 の場合、親コンテナーにはすでにある程度の長さが存在します。

彼らは、数字 1 を追加して画像を表示していました。そのため、カルーセルは、配列内の画像のインデックス番号に従って、画像を 1 つ前にスライドさせます。たとえば、コンテナー内に 10 個の画像があり、その 1 つを currentImage 変数に追加した場合、Math.min によって計算される値は「1」になります。次に、別の「1」を追加すると、現在の画像は 2 になり、2 mod 10 は 2 であるため、Math.min によって値は 2 になります。この特定の例では、スライダーのゲームが変更されます。作ろうとしています。これが私の目に留まったコードです:

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)}`);
}

コメントにある Richard Kichenama のソリューションの優れた点は、Math.max を使用して値が 0 を下回らないようにすることと、Math.min を使用して、変換値が最大長に達するまで変換値を計算することにあります。画像配列

さて、空白の問題をどうやって解決すればいいでしょうか?子 div の全長を取得するには、すべての子 div のマージンを考慮し、それらを合計する必要がありました。その後、最後の子に到達するとスライダーの動きが停止するはずです。これは、合計幅がすべての子の幅とそのマージンの合計であることを意味します。

しかし、別の問題に遭遇しました。一部の div が既にコンテナーに表示されており、再び行き詰ってしまいました。幸運なことに、私の友人が助けに来てくれました。この問題について彼らと話し合った結果、私は次のように理解しました:

子の div の全体の長さを考慮することができませんでした。コンテナの長さとほぼ同じ量の空白が残されました。解決策は、子の全長 (マージンを含む) から親コンテナの長さを減算することでした。この調整により、空白の問題が解決されました。ふう!

コード例の中には、「カウンター」のような変数が含まれているものもあります。これは翻訳プロパティの「カウンター」として機能しました。この変数が増加すると、translate プロパティも増加します。次と前のボタンの Math.min プロパティと Math.max プロパティを分離しました。その方が便利で簡単でした。

私が参照した例では、コードは配列の長さを使用してスライド距離を決定していましたが、友人との以前の議論によれば、空白を考慮する必要があるため、配列の長さを減算する必要がありました。コンテナ。このようにして、div が特定の量だけ移動できるようにし、末尾の余分なスペースを回避しました。

また、john smilga のチュートリアルのおかげで、項目の幅、高さ、上部のプロパティを取得する方法を学びました。適切な値を適用するのは大変でしたが、値の一部が文字列であり、数値に変換する必要があることを知るのも大変でした。 Google で簡単に見つけて、「parseFloat」 を紹介しました。

また、大きな画面には 3 つの div だけを表示し、小さな画面には 2 つの div だけを表示する方法を教えてくれる、別の役立つリソースも見つけました。コツは、コンテナの幅の 100% を 3 (小さい画面の場合は 2) で割って、マージンを差し引くことでした。これにより、コンテナ内に完全に収まる同じサイズの div が可能になりました (とても賢いですね!)。最後に、最終的な関数をチェックアウトするには、私の GitHub にアクセスしてください。ここに私のリポジトリへのリンクがあります。

サイズ変更用のウィンドウ イベント リスナーは、コンテナ内の位置合わせの問題を修正する上で非常に重要でした。サイズ変更時にオフセットをリセットすることで、「スタイルのないコンテンツのフラッシュ」(FOUC) 問題に対処しました。 maxOffset の計算方法を理解するのを手伝ってくれた友人に感謝しなければなりません。これはまさにゲームチェンジャーでした。

最後に、経験豊富な開発者の皆様に一言お願いします。皆さんが共有するすべての言葉が、この分野に不慣れな開発者の助けになります。ですから、あなた側からの情報を投稿し続けてください。私たちは向こう側で熱心に学びたいと思って待っています。ありがとう!

以上がAPI 時間別データの応答性の高い JavaScript カルーセルの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。