js・jquery

jsを使用してページ読み込み時に要素の順番をランダムに変更する

あるギャラリーサイトを作成しているときに、要件として

ディレクターさん

ページ読み込みのたびにギャラリーの表示順をランダムで変更できますか?

と相談されました。

クラスをつけてcssでorderで順番を変更しても良いけどめんどくさそう…

jsでできたら楽かな?と思ったのですがなかなか調べても出てこなかったのでコード書いて実装しました。

では早速いってみましょう。

まずはコードから

See the Pen jsでページ読み込み時にリストの順番をランダムに変更する by 東野江里 (@anyxfbuk-the-scripter) on CodePen.

何度かページ読み込んでもらえればランダム表示になっているのがわかると思います。

解説

html

<ul class="list">
  <li class="list-item">リスト①</li>
  <li class="list-item">リスト②</li>
  <li class="list-item">リスト③</li>
  <li class="list-item">リスト④</li>
  <li class="list-item">リスト⑤</li>
  <li class="list-item">リスト⑥</li>
  <li class="list-item">リスト⑦</li>
  <li class="list-item">リスト⑧</li>
  <li class="list-item">リスト⑨</li>
  <li class="list-item">リスト⑩</li>
</ul>

特筆すべきことはないですが、並べ替えたい要素には同じクラス(今回はlist-item)をつけて、同じ階層に並べてください。

cssは今回はつけていないので各々でどうぞ。

js

1. shuffleElements();

shuffleElements();

ページ読み込み時に shuffleElements 関数が実行されます。リストアイテムをシャッフルするのがこの関数の目的です。

2. randomBox の取得

let randomBox = document.querySelectorAll('.list');

.list クラスを持つ要素をすべて取得し、randomBox という変数に格納します。これは NodeList と呼ばれる配列風のオブジェクトで、複数の .list 要素を操作するために使われます。

3.要素が存在するかのチェック

if (!randomBox || randomBox === 0) {
  return;
}

.list 要素が存在しない場合や、randomBox が空の場合には何もしないで関数を終了します。これにより、エラーを防ぎます。

4.各 .list 内の .list-item を取得

for (let i = 0; i < randomBox.length; i++) {
  let elements = randomBox[i].querySelectorAll('.list-item');

取得した .list 要素のそれぞれに対してループを回し、各 .list の中にある .list-item 要素をすべて取得して elements に格納します。

5. .list-item が存在するかのチェック

if (!elements || elements.length === 0) {
  return;
}

.list-item 要素が存在しない場合は、関数を終了します。

6. Array.from() を使って配列に変換

let elementsArray = Array.from(elements);

NodeList は通常の配列ではないため、Array.from() を使って配列に変換しています。これにより、配列操作がしやすくなります。

7.Fisher-Yatesアルゴリズムで配列をシャッフル

for (let j = elementsArray.length - 1; j > 0; j--) {
  let randomIndex = Math.floor(Math.random() * (j + 1));
  [elementsArray[j], elementsArray[randomIndex]] = [elementsArray[randomIndex], elementsArray[j]];
}

Fisher-Yatesアルゴリズムを使用して、配列をランダムに並び替えます。randomIndex には、0 から j の範囲でランダムなインデックスを生成し、elementsArray[j]elementsArray[randomIndex] を入れ替えます。この操作をリストの末尾から開始し、要素をシャッフルします。

8.元のリストをクリア

while (randomBox[i].firstChild) {
  randomBox[i].removeChild(randomBox[i].firstChild);
}

.list 内のすべての子要素を削除します。これにより、既存の .list-item 要素が一旦消去されます。

9.シャッフルされた要素を再配置

elementsArray.forEach(function(element) {
  randomBox[i].appendChild(element);
});

シャッフルされた elementsArray の要素を .list 内に再び追加します。appendChild を使って、並び替えた要素を元の .list に再挿入しています。

まとめ

アルゴリズムとしては

  1. .list の各リストにある .list-item をランダムにシャッフル
  2. 元の .list の内容をクリアし、シャッフル後の順番で .list-item を再配置

という感じです。なので、.listが複数あってもすべて同じようにランダム表示のコードが動くはずです。

ぜひ使ってみてください。

もしわからないことあれば質問ください!

記事にしてほしい・解説してほしい内容のリクエストもお待ちしています。

プログラミングに興味がある方へ

プログラミングに興味があるけど踏み出すのに勇気がいる…
始めてみたけど進め方がわからない、誰かに質問したい…
ネットの教材は高くて手が出ない…
案件を取ってみたけど納品までたどり着けない…

家庭教師の経験を活かし、そんな方のお手伝いをしたいと思っています。

30万もする悪質で高額なコンテンツマーケティングに騙される前に、相談してみませんか?
相談はもちろん無料です。

こちらから、ぜひお気軽にお問い合わせください。
お仕事のご相談や記事にしてほしい内容のリクエストもお待ちしています!

-js・jquery