GitHub Pages で一部の画像だけ表示されない

投稿者: Anonymous

以下です。よろしければご回答のほど、よろしくお願いいたします・・!

聞きたいこと

GitHub Pagesにて公開したページにて、imgフォルダ内の一部の画像のみ表示されない。

対象URL

https://yukinoshita1103.github.io/leopaquiz/quiz.html

詳細

クイズのWebアプリ。
選択肢として、imgディレクトリに置いた画像をランダムに表示させたいです。
しかし、imgディレクトリにある、
「スーパーマックスノー」
「トレンパーアルビノ」
「ハイポタンジェリン」
「ブレイジングブリザード」
のみが404となり、表示されません。

ローカルでの挙動確認は確認済みで、画像の上げ直し、ファイル名をjsファイルの文言をコピペしてリネームも済みです。
相対パスになっていないことも確認済みです。

画像ファイルの名前が日本語ですが、画像名を英語に変えるのは、現状難し意図考えております。画像名とjsの配列のkeyを同じにしており、そこが同値かどうかで正誤判定しているため。

ファイル内容

GitHub

https://github.com/yukinoshita1103/leopaquiz

HTML

<!DOCTYPE html> <html lang="ja">   <head>
    <meta charaset="UTF-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <title>レオパモルフ検定</title>
    <link
      rel="stylesheet"
      type="text/css"
      href="stylesheet.css"
      media="screen"
    />   </head>   <body>
    <!-- 問題 -->
    <div>
      Q<span id="question-number"></span>:<span id="question-molf-name"></span
      >はどっち?
    </div>
    <!-- 画像を正解/不正解1枚ずつ -->
    <div class="flex">
      <div id="left" onclick="buttonClickLeft(this.id)">aaa</div>
      <div id="right" onclick="buttonClickRight(this.id)">aaa</div>
    </div>
    <!-- 正誤判定 -->
    <div id="marubatsu"></div>
    <!-- タイマー -->
    <div class="timer-wrap">
      <span>
        残り
        <span id="timer-text"></span>
        秒
      </span>
    </div>
    <script type="text/javascript" src="./js/Timer.js"></script>
    <script type="text/javascript" src="./js/Question.js"></script>
    <script type="text/javascript" src="./js/Result.js"></script>   </body> </html>

JavaScript

全モルフを格納
let molfArray = [
  "ハイイエロー",
  "スーパーマックスノー",
  "エメリン",
  "トレンパーアルビノ",
  "ハイポタンジェリン",
  "ブレイジングブリザード",
  "レモンフロスト",
  "バンディット",
  "ギャラクシー",
  "ブラックナイト",
];

// 問題番号をインクリメントする関数を作る。
function increment() {
  questionNumber++;
  questionNumberElement.innerText = questionNumber;
}

// 問題文をランダムに作成する関数を作る。
function molfQuestion() {
  imageNumber = Math.floor(Math.random() * molfArray.length);
  molfQuestionName = molfArray[imageNumber];
  questionElement.innerText = molfQuestionName;
}

// 選択肢がランダムで2枚表示され、正誤判定する関数を作る。
function molfAnswer() {
  // 正解のモルフを用意する。
  imageMolf = '<img src="image/' + molfQuestionName + '.jpg">';
  // 不正解のモルフを用意する。
  do {
    i = Math.floor(Math.random() * molfArray.length);
  } while (i === imageNumber);
  notImageNumber = i;
  notImageMolf = '<img src="image/' + molfArray[notImageNumber] + '.jpg">';
  // 正解と不正解を格納した配列を用意する。
  optionArray = [];
  optionArray[0] = imageMolf;
  optionArray[1] = notImageMolf;
  // 正解と不正解をランダムにエレメントに格納する。
  c = Math.floor(Math.random() * 2);
  do {
    d = Math.floor(Math.random() * 2);
  } while (c === d);
  a = c;
  b = d;
  imageElement.innerHTML = optionArray[a];
  notImageElement.innerHTML = optionArray[b];
  // 左右の画像名を代入
  optionA = optionArray[a]
    .replace('<img src="image/', "")
    .replace('.jpg">', "");
  optionB = optionArray[b]
    .replace('<img src="image/', "")
    .replace('.jpg">', "");
}

// 何問目かを表示する。

let questionNumber = 1;
let questionNumberElement = document.getElementById("question-number");
questionNumberElement.innerText = questionNumber;

// 問題文をランダムに作成。

let imageNumber = Math.floor(Math.random() * molfArray.length);
let molfQuestionName = molfArray[imageNumber];
let questionElement = document.getElementById("question-molf-name");
questionElement.innerText = molfQuestionName;

// 正解のモルフを用意する。

let imageElement = document.getElementById("left");
let imageMolf = '<img src="image/' + molfQuestionName + '.jpg">';
// imageElement.innerHTML = imageMolf;

// 不正解のモルフを用意する。

do {
  i = Math.floor(Math.random() * molfArray.length);
} while (i === imageNumber);
let notImageNumber = i;
let notImageElement = document.getElementById("right");
let notImageMolf = '<img src="image/' + molfArray[notImageNumber] + '.jpg">';
// notImageElement.innerHTML = notImageMolf;

// 正解と不正解を格納した配列を用意する。

let optionArray = [];
optionArray[0] = imageMolf;
optionArray[1] = notImageMolf;

// 正解と不正解をランダムにエレメントに格納する。

c = Math.floor(Math.random() * 2);
do {
  d = Math.floor(Math.random() * 2);
} while (c === d);

a = c;
b = d;

imageElement.innerHTML = optionArray[a];
notImageElement.innerHTML = optionArray[b];

// 左右の画像名を代入

let optionA = optionArray[a]
  .replace('<img src="image/', "")
  .replace('.jpg">', "");
let optionB = optionArray[b]
  .replace('<img src="image/', "")
  .replace('.jpg">', "");

// 左の画像をクリックして、正誤ごとに処理を行う。

function buttonClickLeft() {
  if (optionA === molfQuestionName) {
    console.log("正解");
    // 正解と表示される。
    let marubatsuElement = document.getElementById("marubatsu");
    marubatsuElement.innerText = "正解だよん";
    // 正解表示のN秒後、正解という表示が非表示になる。
    value = "";
    setTimeout(() => {
      marubatsuElement.innerText = value;
    }, 300);
    // 正解表示のN秒後、問題番号がインクリメントされる。
    setTimeout(increment, 300);
    //  正解表示のN秒後、問題名がランダムに表示される関数を表示。
    setTimeout(molfQuestion, 300);
    //  正解表示の2秒後、選択肢がランダムで2枚表示され、正誤判定する関数を利用。
    setTimeout(molfAnswer, 300);
    //  正解表示のN秒後、タイマーがリセットされる。
    setTimeout(() => {
      originalTime = 999;
      timerElement.innerText = originalTime;
    }, 300);
  } else {
    console.log("不正解");
    // 不正解と表示される。
    let marubatsuElement = document.getElementById("marubatsu");
    marubatsuElement.innerText = "間違いじゃぼけ";
    // 得点を用意する。
    let scr = questionNumber - 1;
    console.log(scr);
    window.localStorage.setItem("result", scr);
    // 不正解表示のN秒後、ページが遷移される。
    setTimeout(() => {
      window.location.href = "./consequence.html";
    }, 300);
  }
}

// 右をクリックして、正解の場合、正解とログする。

function buttonClickRight() {
  if (optionB === molfQuestionName) {
    console.log("正解");
    // 正解と表示される。
    let marubatsuElement = document.getElementById("marubatsu");
    marubatsuElement.innerText = "正解だよん";
    // 正解表示のN秒後、正解という表示が非表示になる。
    value = "";
    setTimeout(function () {
      marubatsuElement.innerText = value;
    }, 300);
    // 正解表示の2秒後、問題番号がインクリメントされる。
    setTimeout(increment, 300);
    //  正解表示の2秒後、問題名がランダムに表示される関数を表示。
    setTimeout(molfQuestion, 300);
    //  正解表示の2秒後、選択肢がランダムで2枚表示され、正誤判定する関数を利用。
    setTimeout(molfAnswer, 300);
    //  正解表示のN秒後、タイマーがリセットされる。
    setTimeout(() => {
      originalTime = 999;
      timerElement.innerText = originalTime;
    }, 300);
  } else {
    console.log("不正解");
    // 不正解と表示される。
    let marubatsuElement = document.getElementById("marubatsu");
    marubatsuElement.innerText = "間違いじゃぼけ";
    // 得点を用意する。
    let scr = questionNumber - 1;
    console.log(scr);
    window.localStorage.setItem("result", scr);
    // 不正解表示のN秒後、ページが遷移される。
    setTimeout(() => {
      window.location.href = "./consequence.html";
    }, 300);
  }
}

解決

アクセスする日本語パスととWebサーバーの提供パスが実際は違うためエラーとなっています。
例として「スーパーマックスノー」の画像URLです

エラー
https://yukinoshita1103.github.io/leopaquiz/image/%E3%82%B9%E3%83%BC%E3%83%91%E3%83%BC%E3%83%9E%E3%83%83%E3%82%AF%E3%82%B9%E3%83%8E%E3%83%BC.jpg

成功
https://yukinoshita1103.github.io/leopaquiz/image/%E3%82%B9%E3%83%BC%E3%83%8F%E3%82%9A%E3%83%BC%E3%83%9E%E3%83%83%E3%82%AF%E3%82%B9%E3%83%8E%E3%83%BC.jpg

見た目上一緒ですが「パ」の文字がデータ的には違います。
パのハと濁点を一緒のデータとするか別々の文字として管理するかで違いがでています。(詳しくはUnicode正規化のキーワードで調べてみてください)

今回は以下のサイトで スーパーマックスノー の文字を入力し、非正規化の文字をコピーすると成功しました。molfArray 内の日本語を一度変換すれば成功するのではないかと思います
https://dencode.com/ja/string/unicode-normalization

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *