![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?8acaa2e)
保守性の高いコードを書きたいです。JavaScriptでdocument.write("<div id='main'></div>")みたいに書いて、後でこの要素にいろいろなコードでdocument.getElementById('main').innerHTMLします。しかし、その後id名mainを他の名前に変えると、多くのソースコードを手作業で変更しなくてはなりません。この手間を削減するJavaScriptの書き方はありますか?
例えば、
<table id="board">
<tr>
<td id="b0_0">A</td>
<td id="b0_1">A</td>
<td id="b0_2">A</td>
<td id="b0_3">A</td>
・
・
・
上記のようなHTMLを作成する、以下のようなコードがあります。
<table id='board'></table>
<script>
var content = "";
for(i = 0; i < 5; i++){
content += "<tr>"
for(j = 0; j < 4; j++){
content += "<td id='b"+ i + "_" + j +"'>A</td>"
}
content += "</tr>"
}
$('table#board').html(content) // JQueryを使っているつもりです
</script>
このコードの問題点は少なくとも2つあって、
1つは、2重ループ内の「content += "<td id='b"+ i + "_" + j +"'>A</td>"」が読みづらいことです。
2つ目は、今は td id='b0_1'のような形式ですが、このid名を変更しようと思ったときに、変更が容易ではないことです。
特に2つ目は、いろいろな場所にあるコードから$('table#board td#b1_1').html('B')のような操作をしていると、かなり変更が大変です。
こういったことを乗り越えるためのJavaScriptのコード設計法(?)やIDEやライブラリなどがありましたら教えて下さい。よろしくお願いします
No.3ベストアンサー
- 回答日時:
保守性を高めたい、ということですよね。
であるならば、オブジェクト化を進めることだと思います。・マジックナンバー、マジックストリングを排除する
コード内に直接書かれている意味がわからないリテラルのことです。idのmainなどもそうですね。こうしたものはすべてオブジェクト内に定数プロパティとしてまとめておき、それを参照する形で記述します。例えば、こんなオブジェクトを定義しておき、
function Literal() {
var main = "main";
this.main = function(){ return main; }
}
var literal = new Literal();
innerHTMLではこのようにします。
document.getElementById(literal.main()).innerHTML = ……
コード内で"main"を参照する部分はすべてliteral.main()を使います。こうすれば、後で名前を変更したいときは、Literalのvar mainの値を書き換えるだけです。
・処理のメソッド化
処理専用のオブジェクトを用意し、そこに具体的な処理をすべてメソッドとしてまとめます。例えばテーブルを変数contentにまとめている処理なども、こんな感じにします。
function ContentBuilder() {
this.getTable = function(prefix, arraydata){
var content = "";
for(i = 0; i < arraydata.length; i++){
var row_array = arraydata[i];
content += "<tr>";
for(j = 0; j < row_array.length; j++){
content += "<td id='" + prefix + i + "_" + j +"'>" + row_array[j] + "</td>";
}
content += "</tr>";
}
return content;
}
}
var builder = new ContentBuilder();
これで、builderのgetTableを呼び出すことでテーブルのコードが得られるようになります。こんな感じですね。
var data = [
['a','b','c'],
['あ','い','う'],
[1, 2, 3]
];
document.write(builder.getTable("xxx",data));
生成されるタグのidがどのように設定されているか確認してみてください。引数のプレフィクスを変えればIDもすべて変わります。
このように、「変数・定数をすべて1つのオブジェクトにまとめる」「処理はオブジェクトのメソッドにまとめる」というようにしていき、全ての値や処理は必ずこれらのオブジェクトのメソッドを呼び出すようにします。
こうすれば、後で修正する場合も、オブジェクトのプロパティなどを変更すれば、すべてのところで反映されます。更に、定義したオブジェクト類は別ファイルに切り離し、そのスクリプトファイルをロードするようにすれば、ページデザインと処理(ビジネスロジック)も切り離し別々に管理できます。
JavaScriptはオブジェクト指向言語ですから、それを活用しない手はありません。オブジェクト指向についていろいろ調べてみるとよいでしょう。
ご回答ありがとうございます!
JavaScriptでのオブジェクト指向の活用法がわかった気がします!私はJavaをやっていて、より洗練されたオブジェクト指向をもつScalaにも魅力を感じてるので、オブジェクト指向の発想は分かります。JavaScriptは、はっきりとしたクラスはないし(と思っていて)、オブジェクト指向で組もうとすることはありませんでした。
Javaで磨いたオブジェクト指向をこれからはJavaScriptでも発揮したいと思います。ありがとうございました。
No.4
- 回答日時:
そういったケースでは、IDを1つ1つ付けるべきではありません。
行数、列数が分かっていれば('#board td')で一連のリストとして取得するか、
どうしても二次元リストが良ければ('#board tr')で取得してその後('td')で取得すればできます。
ご回答ありがとうございます
私の例が悪すぎました。別に例はtableでなくても良かったです。単に幾つか入れ子になる自然なHTMLを書こうとしただけなんです。
No.2
- 回答日時:
こんな感じでどうでしょう。
2つ目の「変更が容易ではない」の意味がイマイチよく分かりませんが、1つ目の「読みづらいこと」は改善しているし、もしかしたらこれで2つ目も解決したことになるのではと思います。// コードの先頭辺りに定数として書く。「var content = "";」の前かな
var TD_BASE = "<td id='【ID】'>A</td>";
…
for (var j = 0; j < 4; j++) {
var id = "b" + i + "_" + j;
content += TD_BASE.replace("【ID】", id);
}
また、「var TD_BASE = "<td id='【ID】'>A</td>";」ではなく
「var TD_BASE = "<td id='b【row】_【col】'>A</td>";」などとし、replaceを2つ続けるようにしてもいいと思います。
それからfor文内のインデックス変数の部分ですが、「var j = 0」と明示的に書いた方がいいですよ。そうでないとグローバル変数を使うことになります。このケースでは問題は起きませんが、例えばループ内で関数を呼んでいて、その関数の中でもfor文を使っている場合には、同一の変数を使うことになってしまい正しく動かなくなりますので。
この回答への補足
お礼に書き忘れました。
for文の件ありがとうございます。varつけていいことを知りませんでした。for(i=...だと for(window.i= ...になっちゃうんですかね?
ご回答有難うございます。
私の言葉が足りなかったです。
結局やりたいことは、Javaの開発環境Eclipseにある変数名変更する機能がある開発環境とかがあるといいんですけどね。Eclipseだと変数にカーソルを当てて特定のショートカットキーを押すとその変数を使用しているすべての箇所の変数名が編集できるんです。そういった感じ、簡易にid名を変更できたらいいなと思っていました。
しかし、JavaScriptは文字列のなかにコードがあるので、Javaのようにある識別子がどこで使われているか解析するのは困難そうなので、無理なのは覚悟しているのですが。
Webサービスを大規模開発している人たちはどのようにid名などをを管理しているのか気になります。
No.1
- 回答日時:
少々面倒ですが、JavaScript に備わっている DOM を利用するのがもっとも素直でしょう
// 行を作る
var row = document.createElement('tr');
document.getElementById('board').appendChild(row);
// 欄を作る
var cel = document.createElement('td');
cel.id = 'b' + i + '_' + j;
cel.textContent = 'A';
row.appendChild(cel);
jQuery を使っているならば、DOM の記述を多少は簡略化できます
// 行を作る
var row = $('<tr/>').appendTo('table#board');
// 欄を作る
$("<td/>").attr('id', 'b' + i + "_" + j).text('A').appendTo(row);
ご回答ありがとうございます。
DOMを使うのもひとつの手ですね。ただ、結局innerHTMLを使う時と変わらないですね。'b' + i + '_' + jは結局ありますし、
"b{i}_{j}"みたいな記法出来なんですかね?
もしくは、Cのフォーマット指定のようにformat("b%v_%v", i, j)のような関数が文字列を返すとか?ないですかね?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- AJAX JavascriptからPHPへのAjax通信でnullが返ってくる 3 2022/08/03 22:00
- JavaScript EasyUIのSubGrid(jquery)におけるObjectに入れた連想配列について 1 2022/05/02 11:21
- Visual Basic(VBA) Selenium.ChromeDriverの使い方について 7 2022/09/22 06:43
- HTML・CSS テーブルタグのセルの幅の一部だけを指定 1 2023/03/12 12:02
- PHP htmlで複数の個数入力欄を表示させるには 1 2022/09/20 03:11
- JavaScript jQueryで同じクラス名のものを別物として扱いたい 1 2022/06/17 14:14
- HTML・CSS 【CSS】:hasで可能? imgを含むtr要素を選択したい 1 2022/11/17 14:36
- JavaScript javascriptでテーブルに追加した項目のid追加してローカルストレージを操作したい 5 2023/01/01 15:52
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/07 21:04
- HTML・CSS 自身のHPにYouTube動画を貼り付けるのが出来なくなり困ってます 1 2022/11/11 10:44
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
tableの任意行にfocusをあてる
-
一覧から選択した行の行番号を...
-
テーブルの変数について
-
特定<table>内の<td>の色を変える
-
JavaScriptでテーブルをクリッ...
-
フォームに入力したテキストを...
-
チェックボックスにチェックが...
-
至急!GetElementById でtdの...
-
Tablesorter カタカナで並び替え
-
セルをドラッグで選択するときに、
-
onMouseOverで複数(?)のセル...
-
プルダウンで選択すると、DBの...
-
IE以外でdisplay:noneで隠した...
-
月間予定表の作り方
-
jquery datatablesを使用 イン...
-
JavaScriptでテーブルの行入れ替え
-
sed を使って文字列削除
-
td:nth-childを使ってa要素を取...
-
テーブル列の表示・非表示機能...
-
JSで、テーブルのある行のみ、...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ハイパーリンクを別ウインドウ...
-
プルダウンで選択すると、DBの...
-
一覧から選択した行の行番号を...
-
tableの任意行にfocusをあてる
-
特定<table>内の<td>の色を変える
-
JavaScriptで特定のtdタグにcla...
-
至急!GetElementById でtdの...
-
マウスをブラウザの外に出した...
-
【UWSC】HTML内のある部分を抽...
-
スクロールバーの表示位置を変...
-
クリックされた罫表セルの行番...
-
テーブルの変数について
-
動的なtableの値を取得したい
-
特定の文字列を挿入
-
テーブル内に表示されている数...
-
javascript クリックすると、あ...
-
テーブルの項目の値取得
-
javascriptで質問です。 displa...
-
Tablesorteを2行一組でソートする
-
jspでのArrayListの値の表示
おすすめ情報