LoginSignup
61
73

More than 5 years have passed since last update.

javaScript(jQuery)のインクリメンタルサーチで、全ての行に解説をつけてみた。

Last updated at Posted at 2017-01-25

作ったもの

fruitsという配列群の中からインクリメンタルサーチをするJavaScript。
スクリーンショット 2017-01-25 21.46.26.png

仕様

  • 1文字打つごとに検索
  • スペースで分けて検索
  • フォームに何もないときちんと結果が全部消える
  • 当てはまる検索結果が無いときにはそれを表示

JavaScriptのコード (jQuery)

main.js

var fruits = ['apple', 'apricot', 'avocado', 'blueberry', 'cherry', 'coconut', 'cranberry', 'dragonfruit', 'durian', 'grape', 'grapefruit', 'guava', 'kiwi fruit', 'lemon', 'lime', 'lychee', 'mango', 'melon', 'watermelon', 'miracle fruit', 'orange', 'bloodorange','clementine','mandarine','tangerine','papaya','passionfruit','peach','pear','persimmon','physalis','plum/prune','pineapple','pomegranate','raspberry','rambutan','star fruit','strawberry'];

$(function() {
  var list = $("#list");
  // id="list"を持つ変数を定義
  var preWord;
  // 入力結果と比較するための変数preWordを設定

  function appendList(word) {
    var item = $('<li class="list">').append(word);
    // class="list"で削除という命令のため、全てのアイテムにclass="list"を追加
    list.append(item);
    // var list = $("#list")のlistの中に、class="list"を持ったitemを追加
  }

  function editElement(element) {
    var result = "^" + element;
    // mapで回ってきた配列の各要素の前に^を付け加える
    return result;
  }

  $("#keyword").on("keyup", function() {
    // id="keyword"のキーが押されて上がった時に発火する。
    var input = $("#keyword").val();
    // 変数inputを設定し、id="keyword"のバリューを中に入れる
    var inputs = input.split(" ").filter(function(e) { return e; });
    // splitを使い空白で切り新しい配列を形成。aスペース3つbの場合、["a", "", "", "b"]となる。 ※ 1 分け方の解説
    // filterでfunction(e)のeに配列がそれぞれ入り、true or falseでtrueのもののみ返す。""はfalseになるため消える。 ※ 2 filterについての解説
    var newInputs = inputs.map(editElement);
    // 後の正規化表現のために、配列の各要素に^を付け加える。(ex)^ap  文字の先頭がapのときマッチ
    var word = newInputs.join("|");
    // 後の正規化表現のために、配列の各要素を|を使って連結。(ex) a|b  aまたはbにマッチ
    // この時点で、最初の入力が a b なら、^a|^b のように加工されており、先頭aもしくは先頭bにマッチ、となる。
    var reg = RegExp(word);
    // 加工されたwordからパターンマッチの正規化オブジェクトを生成して変数regに入れる。

    if (input.length === 0) {
      $(".list").remove();
      // フォームに値がないときに、listを全て削除する。
    }

    if (word != preWord && input.length !== 0) {
      // word != preWordで値が変わっていることを確認(shiftとか押された時対策)
      // input.length !== 0で何か値が入っていることを確認
      $(".list").remove();
      // class = "list"を全て削除し、リストを空にする
      $.each(fruits, function(i, fruit) {
        if (fruit.match(reg)) {
          // 配列fruitsがreg(正規化オブジェクト)とマッチしていたらappendListする
          appendList(fruit);
        }
      });

      if ($(".list").length === 0) {
        // $(".list").length === 0は当てはまるものがないということなので、その処理。
        appendList("一致する果物はありませんでした");
      }
    }
    preWord = word;
    // preWordにwordを入れてpreWordを更新する
  });
});

※ 1 splitの分け方の解説

splitメソッドは引数に与えられた文字列で分けた配列を返します。
だいたい以下の通りです。
IMG_0488.PNG

※ 2 filterの解説

filterが使われているのは以下の部分です。

var inputs = input.split(" ").filter(function(e) { return e; });

※1の解説を例にして、input.split(" ")の値が[a,"","",b]だったとします。

filterでは、function(e)のeの部分に、eachのように配列の要素を1つずつ入れて判断します。
そして値がtrueだった場合のみ、取り出し、falseの場合は破棄し、新たな配列を形成します。

javascriptでは""はfalseとなるので(他の言語では違ったりします、、、)

a  => true
"" => false
"" => false
b  => true

となり、trueのみを集めた配列["a", "b"]が返されます。

おまけ

htmlとcssのコードも置いておきます。

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
    <script src="main.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="style.css">
  </head>
  <body>
    <div class="form-group">
      <input type='text' id="keyword" class="form-control" placeholder="好きなフルーツを入力してください">
      <button type="button" id="submit" class="btn">検索</button>
    </div>
    <ul id = "list" ></ul>
  </body>
</html>
style.css
#keyword {
  display: inline-block;
  width: 50%;
}
#submit {
  display: inline-block;
  background-color: #6495ed;
  color: #fff;
  padding: 5.5px 20px;
  vertical-align: top;
}

#list {
  padding: 0;
  margin: 0 auto;
  width: 50%;
  list-style: none;
}

li {
  border-radius: 5px;
  box-shadow: 0.5px 0.5px 1px 1px rgba(0,0,0,0.1) inset;
  background-color: #eee;
  margin: 10px;
  padding: 10px;
}

.form-group {
  width: 75%;
  margin: 20px auto;
  text-align: center;
}

番外編;最近買った、面白いもの

・ハンターハンター34巻(6/29)
クロロ VS ヒソカとか、どうやっても面白くなるとしか
・カーテン自動開閉ロボット
カーテンレールに付ける4000円のロボット。
これを付けてから目覚ましなしで起きられる率が上がった。
・衛藤美彩 写真集
「綺麗なお姉さん」が好きな人、ちょっと眺めてるだけで幸せになれますよ。

間違い、指摘、リファクタリングなどお願いいたします。

フォームに値が入っていない場合にclass="list"を空にする設定をもう少しうまく書けるのではと考えています。。。

61
73
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
61
73