JavaScriptとHTMLを分離するために。CareerJavaScriptとHTMLを分離するために。lodash.jsを使ってデータからHTMLを動的生成する方法いなば2016.11.14Web制作フロントエンドShareこんにちは、フロントエンドエンジニアのいなばです。(シングルページアプリケーション)やpjaxを使ったWebサイトなどはもちろん、静的なWebサイトでも、ページの遷移をせずにHTML要素を動的に生成するケースが多くなりましたね。今回は、lodash.jsというライブラリのもつtemplate関数を使ってHTMLを生成する方法を紹介します。HTMLを動的生成する手法ひと昔前は、書き換えたい要素に対してHTML文字列をinnerHTMLするのが、HTMLを動的に生成する方法として一般的だったのではないかと思います。Aclickした要素によってモーダルの中身を書き換えるケースです。HTMLは属性値や中身を空にしてマークアップします。</div></div>clickされた要素のdata属性を使って、モーダルの中身のHTMLの属性値や中身を書き換えます。Bこちらはajaxで取得したデータをもとにHTMLを組み立てるケースでした。JavaScript側でHTMLテンプレートを持つ手法ですが、ES6のテンプレートリテラルを使うことでいくらかすっきりしていますね。</li>`;};JavaScriptコード内にHTMLを持ちたくない上の2つの例では、JavaScript側がHTMLの構造に依存しています。HTML側の修正頻度は高いので、都度JavaScriptをいじらなくて良いほうが修正コストは低くなりますね。HTMLとJavaScriptが分離できていると見通しがよいですし、JavaScriptがシンプルになります。lodash.templateを使うそこで今回は、HTMLとJavaScriptを分離するためにlodash.templateを使ってみようと思います。Riot.jsなどViewを簡単に扱える便利なライブラリもありますが、ライブラリ自体のファイルサイズも小さくはないので、機能要件がそこまで複雑でない場合、自分はよくlodash.templateを使うことが多いです。lodash.jsとは?配列操作などの便利なメソッドが詰まったライブラリです。https://lodash.com/最近では、babelのプラグイン(babel-plugin-transform-runtime)やpollfilライブラリ(core-js)などでES6で追加されたネイティブの関数を先行して使うことができるため、lodash.jsが必要になるケースは今後なくなってくるかとは思います。下記が、lodash.templateの最もシンプルな使用例です。scriptタグでHTMLテンプレートを定義します。次に、lodash.template関数にテンプレートとして使用したいHTML文字列を渡したものを、変数(compile)にキャッシュします。最後に、先ほどキャッシュしたcompile関数に任意のオブジェクトを渡すとHTML文字列が得られるので、HTMLを追加したい要素に対してinnerHTMLしています。CodePen.JavaScriptとHTMLを分離することができたので、HTML側で修正があったとしてもHTMLの修正だけで済みますね。テンプレート内で使える構文テンプレート内ではfor文やif文を使うことができます。CodePen.Docshttps://lodash.com/docs/4.16.2#templateEJS内でlodash.templateを使うEJSのテンプレートの中でlodash.templateを使うと、デリミタがバッティングしてしまうのでEJSのコンパイルができません。下記はデリミタを変更するコードになります。CodePen.Docshttps://lodash.com/docs/4.16.2#templateSettingsデリミタのデフォルトはソースコードのこのあたりにあります。https://github.com/lodash/lodash/blob/master/lodash.js#L130Ajaxと組み合わせるQiitaのAPIを使ってクリックした要素のdata属性をもとに、特定のタグがついた一覧を取得してHTMLを生成するようにしてみました。CodePen.lodash.templateを使う時に注意することlodash.templateを使えばHTMLの生成が簡単におこなえますが、いくつか気をつけなくてはいけないことがあります。SEO的に必要な要素のレンダリングGoogleBotがJavaScriptを解釈できるようになりましたが、bingなどJavaScriptを解釈できないクローラーはまだあります。これはVue.js、Riot.jsなどでも言えますが、最初から必要なHTML要素は極力サーバーサイド側でレンダリングするべきです。先ほどのajaxを使ったデモを少し修正して、生成した一覧の子要素にclickイベントがつくようにしてみました。HTMLが書きかわる度に、一覧の子要素にclickイベントを設置していますが、これはよくないコードです。CodePen.イベントデリゲートを使いましょう一覧の子要素が書きかわる度にclickイベントをつけるのではなく、一覧の親要素($target)にイベントをつけて監視するようにしましょう。$targetの子要素(.js-item)が100個でも200個でもイベントの数は1つですみますし、HTMLが書きかわる際にイベントを削除する手間も不要になります。メモリリークを起こすリスクも下がります。alert(id);});終わりにLIGのフロントエンドチームでは週に2回、立候補者がテーマを自由に決めて発表する社内勉強会を開催しています。その会で行った案件のソースコードレビューで、HTML要素を動的に生成するケースがたまたま続き、また、社内のフロントエンドの間でlodash.templateの認知度があまりなかったので、社内向け勉強会で発表した内容をブログにしてみました。Vue.js、Riot.jsなどを使うほどでもない要件のときの参考になれば幸いです。LIGはWebサイト制作を支援しています。ご興味のある方は事業ぺージをぜひご覧ください。このメンバーの記事をもっと読むフロントエンドエンジニアのいなばです。LIGではAngularやVueなどのフレームワークを使った中~大規模のWebアプリケーション開発、フロントエンドエンジニアの育成などを担当しています。好きなものはカフェインとカプサイシン。趣味はランニングと一眼レフです。この記事のリンクをコピーするHomeWeb制作フロントエンドJavaScriptとHTMLを分離するために。PopularPR連載一覧イベント情報Web制作デザインTechnologyAIオウンドメディアSEO対策アプリ開発システム。