マジックナンバーを排除して、保守性の高いコードを書きたいです。前回も保守性を高めたいと質問させていただきお世話になりました。
例えば、
<table border="1">
<tr>
<td onclick="users['NkxyZ'].show();">User</td>
</tr>
<tr>
<td onclick="users['BkcSk'].show();">User</td>
</tr>
<tr>
<td onclick="users['HnViOj'].show();">User</td>
</tr>
</table>
上記のHTMLを生成する、以下のコードがあります
<script> // メイン
var users = {'NkxyZ': new User("Taro", 41),
'BkcSk': new User("Hanako", 17),
'HnViOj': new User("Harushige", 8)};
var usersTable = new UsersTableBuilder();
document.write(usersTable.getTable(users));
</script>
<script> // 以下のコードは外部ファイルで、読み込み済みです
// ユーザを管理するクラス
var User = function(name, age){
this.name = name;
this.age = age;
}
User.prototype.show = function(){
alert(this.name +" ("+ this.age+")");
}
// ユーザテーブルを返すクラス
var UsersTableBuilder = function(){
this.tagId = 'users_table';
}
UsersTableBuilder.prototype.getTable = function(users){
var out = "<table border='1'>";
for(var id in users){
out += "<tr><td onclick=\"users['"+ id +"'].show();\">User</td></tr>"
}
out += "</table>";
return out;
}
</script>
このコードで私が一番気に入らないのは、UsersTableBuilderのgetTable()メソッドです。このメソッドのfor文内の
"<tr><td onclick=\"users['"+ id +"'].show();\">User</td></tr>" では
User#show()メソッドが文字列で表現されてしまっています。show()がマジックナンバーぽくなってしまっています。このままでは、Userクラスでshow()メソッドの名前を変えた時などに、変更し忘れになるかもしれません。
JavaのEclipseには変数名を変更できるリファクタリング機能がありますが、そのような機能が使えるJavaScriptの開発環境の時、文字列の状態のコードだと検出できなさそうなので、どうにかして、プログラムの文字列表現から抜け出したいです。
よろしくお願いします。
No.3ベストアンサー
- 回答日時:
> プログラムの文字列表現から抜け出したい
document.write → 親要素.appendChild
<td onclick="処理"> → td要素.addEventListener('click',処理,false)
以下サンプルです
<div id=kokoniTableKake></div>
<script>(function(){ var _;
_ ; var User = function (name, age) {
_ , _ ; this.name = name;
_ , _ ; this.age = age;
_ , _ ; this.show = function(){ alert(this.name +" ("+ this.age+")") };
_ ; }
_ ; var UsersTableBuilder = function(users) {
_ , _ ; this.makeListener = function(user) { return function(event){user.show()} };
_ , _ ; this.appendTableTo = function(id) {
_ , _ , _ ; var tab = document.createElement('table');
_ , _ , _ ; tab.setAttribute('border', true);
_ , _ , _ ; for (var uid in users) {
_ , _ , _ , _ ; var td = document.createElement('td');
_ , _ , _ , _ ; var tr = document.createElement('tr');
_ , _ , _ , _ ; tab.appendChild(tr).appendChild(td);
_ , _ , _ , _ ; var listener = this.makeListener(users[uid]);
_ , _ , _ , _ ; td.addEventListener('click', listener, false); // onclick の代替
_ , _ , _ , _ ; td.textContent = uid;
_ , _ , _ ; }
_ , _ , _ ; document.getElementById(id).appendChild(tab); // write の代替
_ , _ ; };
_ ; };
_ ; var users = { NkxyZ: new User("Taro", 41), BkcSk: new User("Hanako", 17), HnViOj: new User("Harushige", 8) };
_ ; var builder = new UsersTableBuilder(users);
_ ; builder.appendTableTo('kokoniTableKake');
})()</script>
ご回答ありがとうございます。以前にもお世話になりました
コードが分かりやすいです。tableはどこに書くを自由にしたいので、Ogre7077さんのコードを少し変えてappendTableTo()をelementを返すメソッドにしたりしようとかなと思います。ありがとうございました!
No.2
- 回答日時:
UsersTableBuilderをオブジェクトにする意味が消え失せています。
(唯一であるIDが変更できなく・・・)
最初のアドバイスで、dom を使っては?というアドバイスがありましたよね。
個々の要素にaddEventListenerするのは・・・
<!DOCTYPE html>
<meta charset="utf-8">
<title></title>
<style>
table, td {
border:blue 1px solid;
}
td:nth-of-type(1) {
display : none;
}
</style>
<body>
<script>
var User = function (name, age) {
this.name = name;
this.age = age;
}
User.prototype.show = function(){
alert(this.name +" ("+ this.age+")");
}
var users = {
'NkxyZ': new User("Taro", 41),
'BkcSk': new User("Hanako", 17),
'HnViOj': new User("Harushige", 8)
};
function key_name_age (users) {
var result = [];
for (var prop in users)
if (users.hasOwnProperty (prop))
result.push ([prop, users[prop].name, users[prop].age]);
return result;
}
var createTbody =
function (insertTR) {
return function (ary) {
var tbody = document.createElement ('tbody');
ary.forEach (insertTR, tbody);
return tbody;
};
}(function (insertTD) {
return function (record) {
record.forEach (insertTD, this.insertRow (-1));
};
}(function (text) {
this.insertCell (-1).textContent = text;
}));
function callBack (id) {
var obj = users[id];
!obj || obj.show ();
}
function handle (event) {
var e = event.target;
var th, id;
if ('TD' === e.tagName) {
th = e.parentNode.querySelector ('td');
id = th.firstChild.nodeValue;
callBack (id);
}
}
document.body.appendChild (
document.createElement ('table').appendChild (
createTbody (
key_name_age (users))));
document.addEventListener ('click', handle, false);
</script>
ご回答ありがとうございます。いつもお世話になっております。
やっとDOMの良さがわかりました!これなら私の望み通りにコードが組めそうです。少しきになるのがこのコードだと、他にTABLEがあった時にも反応してしまうことです。handle()のifの条件を変えれば対応できるのかもしれませんが…
No.1
- 回答日時:
for(var id in users){
out += "<tr><td onclick=\"users['"+ id +"'].show();\">User</td></tr>"
}
を
for(var id in users){
out += "<tr><td id=\""+ id +"\">User</td></tr>"
}
として、メインの最後に
var tds = document.getElementsByTagName("td");
for (var i = 0; i < tds.length; i++){
tds[i].addEventListener("click", function(){
users[this.id].show();
});
}
を追加するというのはどうでしょうか。一応 IE 11 で動作確認しました。
ご回答ありがとうございます
タグの部分をidだけにして、書いてあとでイベントリスナーを追加する発想はなかったです!ですが、この方法だと引数が複数になった時に困るので、いつも使える解決法ではないのかなと思いました。ありがとうございます
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript EasyUIのSubGrid(jquery)におけるObjectに入れた連想配列について 1 2022/05/02 11:21
- AJAX JavascriptからPHPへのAjax通信でnullが返ってくる 3 2022/08/03 22:00
- Visual Basic(VBA) Selenium.ChromeDriverの使い方について 7 2022/09/22 06:43
- PHP htmlで複数の個数入力欄を表示させるには 1 2022/09/20 03:11
- HTML・CSS テーブルタグのセルの幅の一部だけを指定 1 2023/03/12 12:02
- JavaScript 1日1回引けるJavaScriptおみくじについて 1 2022/12/12 22:28
- JavaScript javascriptでテーブルに追加した項目のid追加してローカルストレージを操作したい 5 2023/01/01 15:52
- JavaScript 追加ボタンを押した際に ok ボタンを押した場合のみ入力値が追記されるようにしたいです 6 2022/05/29 09:57
- その他(プログラミング・Web制作) python 気象データの取得 2 2023/06/20 23:54
- JavaScript jQueryで同じクラス名のものを別物として扱いたい 1 2022/06/17 14:14
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
<JavaScript>tableタグを入力不...
-
Javascriptでテーブルタグの座...
-
jQueryでの親の親の隣の子供の...
-
<iframe>内にHTMLをランダム表...
-
画像クリックでテーブル内背景...
-
指定のテキストをクリックする...
-
クリックごとに文字色が交互に...
-
Table内TDの子要素を移動させた...
-
javascriptで画像をテーブルに...
-
テーブルをクイックソートする...
-
カレンダーに印を付けたい
-
画面表示とともに、テーブルの...
-
テーブルの行数を可変長にした...
-
どこに挿入?
-
マウスが重なったら画像の上に...
-
Javascriptでの開閉リストの質問
-
return trueとreturn falseの用...
-
ボタン2回押しを無効にしたい
-
追加ボタンを押した際に ok ボ...
-
ハイパーリンクを別ウインドウ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
<JavaScript>tableタグを入力不...
-
テーブルの行数を可変長にした...
-
画面表示とともに、テーブルの...
-
selectのonChangeが動作しません
-
【jQuery】tableループ内のIDの...
-
javascriptで画像をテーブルに...
-
Tableの枠線(内・外)色を変更
-
テキストエリアに入力した改行...
-
クリックごとに文字色が交互に...
-
javascript でテーブル操作
-
JQueryでテーブルの行を追加し...
-
javascriptで<table>背景色の取得
-
idの振り直しについて
-
テーブルのセルのクリック時、...
-
<iframe>内にHTMLをランダム表...
-
javascriptでスロットマシン
-
プルダウンメニューを表の中に...
-
連動テーブルのクロスハイライト
-
簡単なJavaスロットマシーンに...
-
jquery にて、アラートダイアロ...
おすすめ情報