配列に入れたキーワードにマッチした文字列をタグで囲むやつを作ってみた。

やりたいこと

とあるサイトで、ページ内にある文章から複数のキーワードに該当する文字列をタグで囲みたいことがありました。
ページが長く、動的に作成されるページだったので、jQueryで対応できないかなとやってみたら案外うまく言ったので、備忘録を兼ねてメモ。

作ったもの

こんなのができました。 codepen.io

devツールなどで見ると、配列に入れたキーワードごとにで囲まれているのがわかると思います。
さらに、キーワードのカテゴリーごとに別々のクラスが付与されています。

キーワードを配列に入れる

まずは配列にキーワードを入れています。

  // キーワードをカテゴリー別に配列に格納
  var sport = ['野球', 'サッカー'];
  var animal = ['犬', '猫'];
  var country = ['日本', 'アメリカ'];
  // カテゴリーを配列に格納
  var keyword = [sport, animal, country];

今回は複数のカテゴリーに分かれてキーワードが存在していたので、それらをまとめてkeywordという配列に入れています。

また、そのほかに使用する変数も用意しておきます。

  var i,j = 0;
  var $sample = $('.sample'); // 対象を指定
  var sourceStr = $sample.html(); // 対象のHTMLを抽出
  var targetStr = keyword; // キーワードを一度変数に格納
  var typeClass; // カテゴリーごとにクラスを振りたいので、変数を用意
  var regExp; // のちにキーワードを正規表現オブジェクトにするので変数を用意しておく

カテゴリーごとにループを回す

配列、変数の用意ができたら、最初にカテゴリーごとにループを回します。

  // カテゴリーごとにループを回す
  for(i in targetStr){
    // キーワードによって付与するクラスを変える
    if (i == 0) {
      typeClass = ' class="sport"';
    }else if (i == 1) {
      typeClass = ' class="animal"';
    }else if (i == 2) {
      typeClass = ' class="country"';
    }
  }

ここでは、カテゴリーごとに違うクラス名を指定したかったので、ループの値( i )によって変数typeClassに異なる値を入れています。

キーワードごとにループを回す

次に、カテゴリーに含まれるキーワードごとにループを回します。

    // カテゴリーに含まれるキーワードごとにループを回す
    for(j in targetStr[i]) {
      regExp = new RegExp( targetStr[i][j], "g" ) ;
      // 置換したものを、一度変数sourceStrに格納
      sourceStr = sourceStr.replace( regExp , "<span" + typeClass + ">$&</span>" ) ;
    }

正規表現で置換したかったので、regExp正規表現オブジェクトを作成しています。

ページ内で引っかかったキーワードを.replaceで置換します。

置換するキーワードを囲む には、キーワードに応じて先ほど用意したクラスを指定します。

ここで使っている &$ は「一致した対象文字を抽出する」というものなので、キーワードを<span class="animal">犬</span> とできます。

ページの内容を置換したもので置き換える

最後に対象を置き換えれば完成です。

$sample.html(sourceStr);

終わりに

配列に入れた複数のキーワードをタグで囲むことができました。
意外とこういう記事が見つからなかったので、苦労しましたがなんとかできました。

もし同じようなことをしたい人がいたら、使ってください。