読者です 読者をやめる 読者になる 読者になる

【JavaScript実践】単語帳作成 1

単語帳を作成してみようと思う。

  1. 英単語とその単語に相当する日本語、例文、優先度をもつデータを取得
  2. 取得したデータを優先度の高い順に並べる
  3. データを先頭から順にユーザに提示
  4. ユーザはそれぞれのデータに対してpositiveもしくはnegativeな反応をする
  5. ユーザの反応によってデータの優先度を変更する
    • negativeの時は該当単語の優先度を下げる
    • positiveの時は該当単語の優先度を上げる

英単語とその単語に相当する日本語、例文、優先度をもつデータを取得

フロントとなるindex.htmlと疑似データとなるseed.jsonを作成

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>Flash Cards</title>
</head>
<body>

  <script src="./scripts/script.js"></script>
</body>
</html>

スクリプトを読み込むだけ。

seed.json

[
  {
    "en": "play",
    "ja": "演奏する",
    "example": "She plays piano well.",
    "weight": 1
  },
  {
    "en": "run",
    "ja": "走る",
    "example": "He runs in the park.",
    "weight": 0
  },
  {
    "en": "eat",
    "ja": "食べる",
    "example": "I eat an orange.",
    "weight": 3
  },
  {
    "en": "walk",
    "ja": "歩く",
    "example": "My father walks every morning.",
    "weight": 2
  },
  {
    "en": "watch",
    "ja": "観る",
    "example": "We watched the movie last week.",
    "weight": 4
  }
]

疑似データを5つ用意した。

scripts/script.js

(function() {
  getWordsData(function(wordsData) {
    console.log(wordsData);
  });

  function getWordsData(callback) {
    var xhr = new XMLHttpRequest();

    xhr.open("GET", "./seed.json");
    xhr.addEventListener("load", function(ev) {
      callback(JSON.parse(ev.target.response));
    });
    xhr.send();
  }
}());

f:id:kosumoro:20160819235745j:plain

データ取得用の関数を作成し、XHRでデータを取得する。

専用の関数でブラックボックス化すれば、後々の変更の際楽になる。

取得したデータを優先度の高い順に並べる

scripts/script.js

(function() {
  getWordsData(function(wordsData) {
    wordsData = sortWordsData(wordsData);

    console.log(wordsData);
  });

  function sortWordsData(wordsData) {
    return wordsData.sort(function(current, next) {
      return next.weight - current.weight;
    });
  }

  // 略
}());

f:id:kosumoro:20160819235701j:plain

sort メソッドを使用して並べ替えを行う。

データを先頭から順にユーザに提示

scripts/script.js

(function() {
  getWordsData(function(wordsData) {
    wordsData = sortWordsData(wordsData);

    wordsData.forEach(function(wordData) {
      showWordData(wordData);
    });
  });

  function showWordData(wordData) {
    alert(JSON.stringify(wordData, null, "  "));
  }

  // 略
}());

f:id:kosumoro:20160820000233j:plain

並べ替えた配列データを forEach メソッドで順番にループさせ、 alert メソッドでユーザに提示している。

ユーザはそれぞれのデータに対してpositiveもしくはnegativeな反応をする

(function() {
  getWordsData(function(wordsData) {
    wordsData = sortWordsData(wordsData);

    wordsData.forEach(function(wordData) {
      showWordData(wordData);
    });
  });

  function showWordData(wordData) {
    var memorized = confirm(JSON.stringify(wordData, null, "  "));

    if(memorized) {
      console.log("OK. The word has been memorized.");
    }
    else {
      console.log("NG. The word has not been memorized yet.");
    }
  }

  // 略
}());

反応の分岐が必要なので alert メソッドを confirm メソッドに変更した。

confirm メソッドは真偽値を返すので、それを利用して処理を分岐している。

ユーザの反応によってデータの優先度を変更する

  • negativeの時は該当単語の優先度を下げる
  • positiveの時は該当単語の優先度を上げる
(function() {
  getWordsData(function(wordsData) {
    wordsData = sortWordsData(wordsData);

    wordsData.forEach(function(wordData) {
      showWordData(wordData);
    });
  });

  function showWordData(wordData) {
    var memorized = confirm(JSON.stringify(wordData, null, "  "));

    if(memorized) {
      wordData = updateWordWeight(wordData, -1);

      console.log("OK. Weight: ", wordData.weight);
    }
    else {
      wordData = updateWordWeight(wordData, 1);

      console.log("NG. Weight: ", wordData.weight);
    }
  }

  function updateWordWeight(wordData, diff) {
    wordData.weight = wordData.weight + diff;

    return wordData;
  }

  // 略
}());

次回以降フロント画面の作成やデータベース連携を考える。