質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.75%

  • JavaScript

    15275questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    6319questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

jqueryでのhtml記述時のコードの可読性の向上のためのアイディア

解決済

回答 7

投稿

  • 評価
  • クリップ 1
  • VIEW 711

cloudspider

score 66

jqueryを使ってhtmlを記述するコードを書いているのですが、jqueryの知識が乏しいのでどのように書くのが一番コードの可読性を高められるのかわかりません。

$('#timeTable').children('.timeRowq')
               .eq(row).children('.subject')
               .eq(col).html('<div class="lessonTitle">'+timeTable[i][5]+
                           '</div><div class="lessonTeacher">'+timeTable[i][6]+
                           '</div><div class="lessonClassroom">'+timeTable[i][7]+
                           '</div><div class="lessonSyllabus" style="display:none;">'+timeTable[i][8]+
                           '</div><div class="lessonCode" style="display:none;">'+timeTable[i][0]+
                           '</div><div class="lessonCol" style="display:none;">'+timeTable[i][1]+
                           '</div><div class="lessonRow" style="display:none;">'+timeTable[i][2]+
                           '</div><div class="lessonTerm" style="display:none;">'+timeTable[i][4]+
                           '</div>');

上のようなコードを書いているのですが、このように書くと</div>が次の行に行ってしまうので可読性が下がっていると思います。
挙動としては問題が起こってないのですが、冗長だし人に見せたときに理解が送れるのではないかと思っています。

こんな書き方があるよだとか、このように書いたほうがいいよという書き方があれば教えて頂けるとうれしいです。
よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 7

checkベストアンサー

+3

 + 演算子

素直に連結する。

var timeTable = [['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']];
var i = 0;
var string = '<div class="lessonTitle">' + timeTable[i][5] + '</div>' +
             '<div class="lessonTeacher">' + timeTable[i][6] + '</div>' +
             '<div class="lessonClassroom">' + timeTable[i][7] + '</div>' +
             '<div class="lessonSyllabus" style="display:none;">' + timeTable[i][8] + '</div>' +
             '<div class="lessonCode" style="display:none;">' + timeTable[i][0] + '</div>' +
             '<div class="lessonCol" style="display:none;">' + timeTable[i][1] + '</div>' +
             '<div class="lessonRow" style="display:none;">' + timeTable[i][2] + '</div>' +
             '<div class="lessonTerm" style="display:none;">' + timeTable[i][4] + '</div>';

console.log(string);

 Array.prototype.join

配列の要素を連結する。

'use strict';
var timeTable = [['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']]];
var i = 0;
var string = ['<div class="lessonTitle">' + timeTable[i][5] + '</div>',
             '<div class="lessonTeacher">' + timeTable[i][6] + '</div>',
             '<div class="lessonClassroom">' + timeTable[i][7] + '</div>',
             '<div class="lessonSyllabus" style="display:none;">' + timeTable[i][8] + '</div>',
             '<div class="lessonCode" style="display:none;">' + timeTable[i][0] + '</div>',
             '<div class="lessonCol" style="display:none;">' + timeTable[i][1] + '</div>',
             '<div class="lessonRow" style="display:none;">' + timeTable[i][2] + '</div>',
             '<div class="lessonTerm" style="display:none;">' + timeTable[i][4] + '</div>'].join('');

console.log(string);

 template要素

確認の為にjQueryオブジェクト(jqueryObject)からHTML文字列(htmlString)に変換していますが、jQueryオブジェクトのままの状態で .append() すると良いと思います。

<template id="sample"><div class="lessonTitle"></div><div class="lessonTeacher"></div><div class="lessonClassroom"></div><div class="lessonSyllabus" style="display:none;"></div><div class="lessonCode" style="display:none;"></div><div class="lessonCol" style="display:none;"></div><div class="lessonRow" style="display:none;"></div><div class="lessonTerm" style="display:none;"></div></template>
<script>
'use strict';
var timeTable = new Map([[4, 'a'], [5, 'b'], [6, 'c'], [-1, 'd'], [7, 'e'], [0, 'f'], [1, 'g'], [2, 'h'], [3, 'i']]);
var jqueryObject = jQuery(document.getElementById('sample').innerHTML);

jqueryObject.each(function (i, div) {
  div.innerHTML = timeTable.get(i);
});

var htmlString = Array.prototype.reduce.call(jqueryObject, function (htmlString, div) {
  return htmlString + div.outerHTML;
}, '');

console.log(htmlString);
jQuery('#timeTable>.timeRowq>.subject>td').eq(0).append(jqueryObject);
<script>

 対応表を用意する

template要素のコードの肝は、「timeTable[i][5]」と「div要素ノードの index 値(0)」の対応表を用意する事にあります。
他にも下記の方法が考えられます。

  • new Map の代わりに二次元配列に対応表を格納する
  • 同じ index 値の値同士が対応するように変数 timeTable の要素の順番を入れ替える
  • 「div要素が持つclass属性値」と「変数 timeTable の index 値」の対応表を用意する

Re: cloudspider さん

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/02 15:19

    回答ありがとうございます。
    上2つは</div>と<div>を2回にわけたら見やすくなるんですね。一見単純そうですが思いつきませんでした。

    一番下のものは僕が知らない物が多かったのでこのコードを参考にして研究させてもらいます。

    キャンセル

  • 2017/07/10 20:52

    今時間をかけてみなさんの回答を一つ一つ研究しているのですが、think49様の
    jQuery(document.getElementById('sample').innerHTML)という記述ですがjQuery(document).~~
    というのはよく見るのですが()の中にgetElementByIdも入っているのは初めてみました。「div.lessonTitle」などが出力されるのは確認し理解したのですが、今後の汎用性も考えて、この書き方が書かれているページとか、この書き方を調べるためのキーワードとかないでしょうか。
    よろしくお願いします。

    キャンセル

  • 2017/07/10 22:52

    document.getElementById('sample').innerHTML の返り値を確認してみて下さい。
    jQuery() にはHTMLタグ文字列を渡した場合に、jQueryオブジェクトに変換する機能があります。
    公式リファレンスには隠し機能でもなければ、全て書かれていますので、そちらを参照する事をお勧めします。
    https://api.jquery.com/jQuery/#jQuery2

    本来はimportNodeを使うべきなのですが、後方互換性の観点から楽をしました。
    Polyfillを適用出来るなら、importNodeの実装が好ましいと思います。
    https://www.html5rocks.com/ja/tutorials/webcomponents/template/

    キャンセル

+2

バックスラッシュを入れることによって、文字列を改行することができます。

改行の直前にバックスラッシュを置くことで、改行をエスケープすることもできます。バックスラッシュと改行の両方が、文字列の値から取り除かれます。
文法とデータ型 - JavaScript | MDN

本当はテンプレートリテラルを使うのがいいんでしょうけれど、IEが未対応です。

Template literal は組み込み式を扱うことができる文字列リテラルです。複数行文字列や文字列内挿機能を使用できます。
テンプレート文字列 - JavaScript | MDN

replace関数を使って、テンプレートもどきを作るのも手ですが、可読性が上がるかどうか、微妙なところ……

'\
<div class="lessonTitle">{__}</div>\
<div class="lessonTeacher">{__}</div>\
<div class="lessonClassroom">{__}</div>\
<div class="lessonSyllabus" style="display:none;">{__}</div>\
<div class="lessonCode" style="display:none;">{__}</div>\
<div class="lessonCol" style="display:none;">{__}</div>\
<div class="lessonRow" style="display:none;">{__}</div>\
<div class="lessonTerm" style="display:none;">{__}</div>\
'
.replace(/{__}/g, function(arr){ return function(){ return arr.shift() } }([
  timeTable[i][5],
  timeTable[i][6],
  timeTable[i][7],
  timeTable[i][8],
  timeTable[i][0],
  timeTable[i][1],
  timeTable[i][2],
  timeTable[i][4]
]));

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/02 15:22

    こんな方法があるとは驚きです。
    試してみます。ありがとうございました。

    キャンセル

+2

普通にappendしてけば良いのでは?

 .eq(col).append($('<div>').addClass('lessonTitle').text(timeTable[i][5]))

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/02 15:21

    シンプルでわかり易くいいですね。
    ありがとうございました。

    キャンセル

+1

可読性という話題はよく見かけますが、コード自体の可読性を限界まで高める方法以外にも、コメントをそれなりに入れておけば十分なんじゃないかと思うことがあります。

という考えで下にコメント付きのコードを書いてみましたがどうでしょうか?

あと、書き出すのがちょっと長いhtmlなので、html()の中に直接書くよりはどこか別の場所で作ったhtmlを書き出す方がメンテナンス性は良いと思います。
例えば、出力するHTMLだけを変更したい、または、書き出し先に追加変更を加えたいってときに()や{}を気にする量が減るかなと

/* test data */
var timeTable = [['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']];
var i = 0;
/* end */


function get_html(){

    /*
     * return html code
     *
        <div class="lessonTitle">hoge</div>
        ...
        <div class="lessonTerm" style="display:none;">piyo</div>
     *
     */

    var html = '',
        list = [
            ['Title',5,false],
            ['Teacher',6,false],
            ['Classroom',7,false],
            ['Syllabus',8,true],
            ['Code',0,true],
            ['Col',1,true],
            ['Row',2,true],
            ['Term',4,true],
        ];

    list.forEach(function(e){
        attr = e[2]?' style="display:none;"':'';
        html += '<div class="lesson'+e[0]+'"'+attr+'>'+timeTable[i][e[1]]+'</div>';
    });

    return html;

}

/* test */
 console.log( get_html() );
/* end */


$('#timeTable').children('.timeRowq')
               .eq(row).children('.subject')
               .eq(col).html(get_html());

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/02 14:35

    簡潔だし読みやすいしメンテナンス性も良さそうで良いですね。
    forEachを知らなかったので勉強してみます。
    ありがとうございました。

    キャンセル

+1

Babelを使ってES6形式でJavaScriptを記述するというのは邪道でしょうか?

ES6形式であれば、文字列に「``」で囲ったテンプレートストリングが使えるので、 変数部分を${変数名}と記述すれば以下のように書き直すことが出来ます。

$('#timeTable').children('.timeRowq')
.eq(row).children('.subject')
.eq(col).html(`  
<div class="lessonTitle">${timeTable[i][5]}</div>  
<div class="lessonClassroom">${timeTable[i][6}</div>  
<div class="lessonClassroom">${timeTable[i][7]}</div>  
<div class="lessonSyllabus" style="display:none;">${timeTable[i][8]}</div>  
<div class="lessonCode" style="display:none;">${timeTable[i][0]}</div>  
<div class="lessonCol" style="display:none;">${timeTable[i][1]}</div>  
<div class="lessonRow" style="display:none;">${timeTable[i][2]}</div>  
<div class="lessonTerm" style="display:none;">${timeTable[i][4]}</div>  
`);

「+」で連結しない分、こちらのが可読性はかなり上がります。

Babelが使える状況であれば、jQueryでこの手のHTML生成を行わずに他のフレームワークを使ってるかもしれませんが・・・

 参考

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/02 16:21

    BabelとReactとES6をただいま絶賛勉強中です!!
    新たなフレームワークを知ることでより楽に書けるようになるのいいですね〜
    ありがとうございました。

    キャンセル

0

jQueryではないですが、lodash.jsなどを使うのはいかがでしょうか?

以下公式からの抜粋のサンプルコードです。

// Use the "interpolate" delimiter to create a compiled template.
var compiled = _.template('hello <%= user %>!');
compiled({ 'user': 'fred' });
// => 'hello fred!'

// Use the HTML "escape" delimiter to escape data property values.
var compiled = _.template('<b><%- value %></b>');
compiled({ 'value': '<script>' });
// => '<b>&lt;script&gt;</b>'

参考リンク

  • Lodash Documentation
    https://lodash.com/docs/4.17.4#template

  • lodash.js (underscore.js)でのtemplateの使い方
    http://qiita.com/nabettu/items/c4c6670e67972b40bbd7

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/02 15:20

    javascriptのフレームワークは豊富すぎますね・・
    lodash.js調べてみます!ありがとうございました。

    キャンセル

0

“use strict”(厳格モード)なら、環境の準備とかせずに利用できますよ。
厳格モードの記述を利用したい部分だけを即時関数でラップすればお手軽です。

(function(){
"use strict";

$('#timeTable').children('.timeRowq')
.eq(row).children('.subject')
.eq(col).html(`  
<div class="lessonTitle">${timeTable[i][5]}</div>  
<div class="lessonClassroom">${timeTable[i][6}</div>  
<div class="lessonClassroom">${timeTable[i][7]}</div>  
<div class="lessonSyllabus" style="display:none;">${timeTable[i][8]}</div>  
<div class="lessonCode" style="display:none;">${timeTable[i][0]}</div>  
<div class="lessonCol" style="display:none;">${timeTable[i][1]}</div>  
<div class="lessonRow" style="display:none;">${timeTable[i][2]}</div>  
<div class="lessonTerm" style="display:none;">${timeTable[i][4]}</div>  
`);
})()

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/10 23:00

    > “use strict”(厳格モード)なら、環境の準備とかせずに利用できますよ。
    テンプレートリテラルには「IE11では使えない」という環境の問題があります。
    http://kangax.github.io/compat-table/es6/#test-template_literals

    キャンセル

  • 2017/07/11 17:16

    IEめ..

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.75%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    15275questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    6319questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。