JavaScript内でdocument.writeなど使用せず綺麗にHTMLを書く方法は何かないでしょうか?
タブインデントや改行など使用した本来のHTMLコードに近い形で、JSONで受け取った値など扱うことを実現したいです。
ライブラリー等でも構いません。
AngularJSを使ったりもしましたが、HTML側で出力する仕様だったので、結果的に意図した動きにはなりませんでした。
もし方法があれば教えていただけますと幸いです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
ベストアンサー
タブインデントや改行など使用した本来のHTMLコードに近い形で、JSONで受け取った値など扱う
想定される環境についての記載がありませんが、新しい機能であるテンプレートリテラルが選択肢となるかもしれません。デスクトップであればIE以外の主要な最新ブラウザは既に使えます。
テンプレートリテラルは、文字列の引用符にバッククォート ` を使用することで、複数行のテキストをそのまま記載することができます。
JavaScript
1var str_normal = "test\ntest\ntest"; 2 3var str_template = `test 4test 5test`; 6 7console.log(str_normal === str_template); //true
もちろん、HTMLも文字列の一種ですので、テンプレートリテラルで定義して、innerHTMLで挿入することができます。
HTML
1<nav></nav> 2 3<script> 4var html = ` 5 <ol> 6 <li><a href="a.html">A</a></li> 7 <li><a href="b.html">B</a></li> 8 <li><a href="c.html">C</a></li> 9 </ol> 10`; 11 12document.querySelector("nav").innerHTML = html; 13</script>
また、テンプレートリテラルでは、${}を使って式を入れることもできます。これを使うと、繰り返し処理を盛り込むこともできます。
HTML
1<main></main> 2 3<script> 4var json = { 5 a01: { 6 title: "article 01", 7 date: "2016/9/18", 8 body: "test test test" 9 }, 10 a02: { 11 title: "article 02", 12 date: "2016/9/19", 13 body: "test test test test" 14 }, 15 a03: { 16 title: "article 03", 17 date: "2016/9/20", 18 body: "test test test test test" 19 } 20}; 21 22var html = ` 23${Object.keys(json).map(function(i) { 24 return ` <article> 25 <h1>${json[i].title}</h1> 26 <h2>${json[i].date}</h2> 27 <p>${json[i].body}</p> 28 </article>`; 29}).join("\n")} 30`; 31 32document.querySelector("main").innerHTML = html; 33</script>
結果として、以下のようなHTMLとなります。
HTML
1<main> 2 <article> 3 <h1>article 01</h1> 4 <h2>2016/9/18</h2> 5 <p>test test test</p> 6 </article> 7 <article> 8 <h1>article 02</h1> 9 <h2>2016/9/19</h2> 10 <p>test test test test</p> 11 </article> 12 <article> 13 <h1>article 03</h1> 14 <h2>2016/9/20</h2> 15 <p>test test test test test</p> 16 </article> 17</main>
こういったテンプレート関係のライブラリも色々あるとは思いますが、素のJavaScriptでも一応このぐらいまではできるということで。
【参考】
Template literal - JavaScript | MDN
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/template_strings
--
2016/9/20 11:11 参考へのリンクが上手く貼れていなかったので修正
投稿2016/09/19 18:50
編集2016/09/20 02:12総合スコア849
0
Function.prototype.toString
個人的にはバッドノウハウの一種だと思いますが、ES5 の範疇でテンプレートリテラル(ES6)を実装したい時には使えます。
JavaScript
1'use strict'; 2var htmlString = function(){/* 3<div> 4 <p>test</p> 5</div> 6*/}.toString().slice(14, -3).trim(); 7console.log(htmlString);
template 要素 (HTML 5)
IE 以外は使えます。
IE 対策に Polyfill を使う必要がありそうです。
所感
私としてはテンプレートリテラル(ES6)、template要素(HTML5)が正道だと考えています。
どちらもブラウザの実装が追い付いていないので、私であれば下記のどちらかを選択します。
- 正規表現の一括置換で対応する
- templateとなるHTMLをサーバに置き、サーバサイドスクリプトで読み込む
どうしてもテンプレートリテラルを使いたい気持ちが強ければ Function.prototype.toString
を使いますが、パフォーマンス面も良くわからないので事前調査が必要だと思います。
Re: poooooo さん
投稿2016/09/20 02:39
総合スコア18162
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
個人的にはRange#createContextualFragment
メソッドを使うのが好きです。
html
1<!DOCTYPE html> 2<head> 3 <title></title> 4 <script type="application/javascript"> 5 document.addEventListener("DOMContentLoaded", () => { 6 const range = document.createRange(); 7 range.selectNodeContents(document.body); 8 const df = range.createContextualFragment('<div>some nodes</div>'); 9 range.startContainer.appendChild(df); // range.startContainer === document.body 10 range.detach(); 11 }, false); 12 </script> 13</head> 14<body> 15 <!-- 省略 --> 16</body> 17</html>
受け取る引数は文字列なので、JSONのプロパティだろうが何だろうが自由に記述できます。
ただ、似たような用途だと一般的にはinnerHTML = '<div>some nodes</div>'
といった書き方を使うことが多いですね。分かりやすいですし。
他にもinsertAdjascentHTML("beforeend", '<div>some nodes</div>');
という書き方もあります。
それぞれ長所短所が違うので、調べてみると面白いです。
投稿2016/09/19 16:46
総合スコア870
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
サンプル
html
1<!DOCTYPE html> 2<html> 3 <head> 4 <title>test</title> 5 <meta charset="UTF-8"> 6 <script type="text/javascript"> 7 function init() { 8 var li = []; 9 var ul = document.createElement('ul'); 10 11 for (var i = 0; i < 4; i++) { 12 li[i] = document.createElement('li'); 13 li[i].innerHTML = 'list' + i; 14 ul.appendChild(li[i]); 15 } 16 17 var body = document.getElementsByTagName('body'); 18 19 for (var i = 0; i < body.length; i++) { 20 body[i].appendChild(ul); 21 } 22 } 23 24 window.addEventListener("load", function () { 25 init(); 26 }); 27 </script> 28 </head> 29 <body> 30 </body> 31</html>
投稿2016/09/19 16:20
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/09/20 00:22 編集
2016/09/20 02:09
2016/09/20 05:44