jQuery のクリックイベントの多重処理を防ぐ方法についてご教授お願いしたく、この場を借りて質問させて頂きました。
タイトル通り、クリックイベントの多重処理を防ぎたいのですが、まずは、問題のソースコードのサンプルをご用意しました。
HTML
1<table id="priceData"> 2 <tr> 3 <th>名前</th> 4 <th>価格</th> 5 </tr> 6 <tr id="rowData"> 7 <td><input type="text" value="商品1"></td> 8 <td><input type="text" value="2980"></td> 9 </tr> 10</table>
商品名の価格を設定するテーブルがあります。ボタンを押すと行が追加される仕組みになっています。
行を追加するプログラムは以下の通りです。
HTML
1<input type="button" id="appendRowButton" value="行追加">
JavaScript
1function appendRow(values) { // values = ['商品%i%', '0'] 2 var dom = ''; 3 4 ~行数を数える処理~ 5 ~valuesに%i%という文字列があった場合は、それを数えた行数に置換する~ 6 7 // 行追加 8 dom += '<tr id="rowData">'; 9 for (var i = 0; i < values.length; i++) { 10 dom += '<td><input type="text" value="<%- values[i] %>"></td>'; 11 } 12 13 var template = _.template(dom); 14 $('#priceData').append(template({ 15 values : values 16 })); 17}
商品名列の値の 「%i%」 について、
[id=rowData] のID数を数えて、%i%をID数に置換します。
テーブルの行をクリックしたら、その行を青色で塗りつぶし、選択した行のデータと行番号を変数に記憶するようにしています。
現行ですと、以下のような形になっています。
JavaScript
1$(function () { 2 setEvent(); 3 4 // 行追加ボタンをクリックした場合 5 $('#appendRowButton').click(function () { 6 setEvent(); 7 }); 8});
JavaScript
1// 行のどこかをクリックした場合 2function setEvent() { 3 $('#priceData').children('tbody').children('[id=rowData]').click(function () { 4 $('#priceData').children('tbody').children('[id=rowData]').each(function (index, element) { 5 クリックした行を青色で塗りつぶし、選択した行のデータと行番号を変数に記憶する 6 それ以外の行は白色で塗りつぶす。 7 }); 8 }); 9}
DOM生成完了時にsetEvent()を呼び出していますが、行を追加した後にもう一度setEvent()を呼び出さないと追加した行に対してイベントが発生しないのです。なので、現状では追加する度にsetEvent()を呼び出しています。
ただ、行を追加すればするほど、行数分setEvent()を繰り返すので、処理の負担も増えます。出来れば、最初のsetEvent()だけでイベント処理を行いたいのですが、動的に追加されたDOMに対するクリックイベントは .on を使うしかないのです。
セレクタ―も機能しないので、 .each も使えないので、現状では行を追加する度に setEvent() を呼び出す方法が一番の解決策となっています。
理想としては、
行を追加したら、既に呼び出されている setEvent() を消して、新たに setEvent() を呼び出すようにしたいのですが。
もっといい方法があれば是非教えて頂きたいです。
以上よろしくお願い致します。
実際の処理画面は以下URLにあります。
座標計算 | Coordinate calculation
以下、実際のソースコード
JavaScript
1*** coordinateCalculation-activity.js *** 2 3$(function () { 4 5 // コンストラクターを生成 6 var listView1 = new ListView(['Name', 'X', 'Y'], 'listView1', $('#dispListView1')); 7 8 listView1.appendRow(['Name%i%', '0', '0']); 9 listView1.setListViewEvent(); 10 11 // 追加ボタンをクリックした場合 12 $('#addButton').click(function () { 13 listView1.appendRow(['Name%i%', '0', '0']); 14 listView1.setListViewEvent(); 15 Calculate(listView1.getAllData(['name', 'x', 'y'])); 16 dispSelectedPointDetail(listView1, 'pointer1', listView1.id, ['name', 'x', 'y']); 17 }) 18 19 // 削除ボタンをクリックした場合 20 $('#delButton').click(function () { 21 listView1.removeRow(listView1.selectedRowData); 22 Calculate(listView1.getAllData(['name', 'x', 'y'])); 23 dispSelectedPointDetail(listView1, 'pointer1', listView1.id, ['name', 'x', 'y']); 24 }); 25 26 // 実行ボタンをクリックした場合 27 $('#actButton').click(function () { 28 Calculate(listView1.getAllData(['name', 'x', 'y'])); 29 dispSelectedPointDetail(listView1, 'pointer1', listView1.id, ['name', 'x', 'y']); 30 }); 31 32 // サブミットした場合 33 $('#listView1Form').submit(function () { 34 Calculate(listView1.getAllData(['name', 'x', 'y'])); 35 dispSelectedPointDetail(listView1, 'pointer1', listView1.id, ['name', 'x', 'y']); 36 }); 37 $('#listView2Form').submit(function () { 38 Calculate(listView1.getAllData(['name', 'x', 'y'])); 39 dispSelectedPointDetail(listView1, 'pointer1', listView1.id, ['name', 'x', 'y']); 40 }); 41 42 ~省略~ 43 44}); 45 46~省略~ 47
JavaScript
1*** list-view.js *** 2 3var ListView = function (columns, id, selector) { 4 5 // 変数を定義 6 this.columns = columns; 7 this.id = id; 8 this.selector = selector; 9 this.selectedRowData; 10 this.selectedRowIndex = 0; 11 12 // メソッドを定義 13 this.appendRow = ListView.appendRow; 14 this.removeRow = ListView.removeRow; 15 this.getCellData = ListView.getCellData; 16 this.getAllData = ListView.getAllData; 17 this.setListViewEvent = ListView.setListViewEvent; 18 19 // ListViewを設置 20 ListView.setListView(columns, id, selector); 21 22}; 23 24// ***************************************************************************** 25// ListViewを設置 26// ***************************************************************************** 27ListView.setListView = function (columns, id, selector) { 28 29 var dom = ''; 30 31 dom += '<table class="list-view" id="' + id + '">'; 32 33 // ヘッダー行を生成 34 dom += '<tr class="-user-select-none">'; 35 36 for (var i = 0; i < columns.length; i++) { 37 38 dom += '<th>' + columns[i] + '</th>'; 39 40 } 41 42 dom += '</tr>'; 43 44 dom += '</table>'; 45 46 var template = _.template(dom); 47 48 selector.prepend(template()); 49 50} 51 52// ***************************************************************************** 53// 行を追加 54// ***************************************************************************** 55ListView.appendRow = function (defaultValues) { 56 57 var dom = ''; 58 59 // 行数を定義 60 var rowLength = $('#' + this.id).children('tbody').children('[id=listViewRowData]').length; 61 62 // 行を追加 63 dom += '<tr id="listViewRowData">'; 64 for (var i = 0; i < this.columns.length; i++) { 65 66 // テキストの初期値にパラメータをセット 67 var regExp = new RegExp('%i%', 'g'); 68 var defaultValue = defaultValues[i].replace(regExp , rowLength); 69 70 dom += '<td>'; 71 dom += '<input type="text" id="listViewColumnValue" value="' + defaultValue + '" spellcheck="false">'; 72 dom += '</td>'; 73 74 } 75 dom += '</tr>'; 76 77 var template = _.template(dom); 78 79 $('#' + this.id).append(template()); 80 81} 82 83// ***************************************************************************** 84// 選択した行を削除 85// ***************************************************************************** 86ListView.removeRow = function (id) { 87 88 var parentThis = this; 89 90 id.remove(); 91 92 $('#' + parentThis.id).children('tbody').children('[id=listViewRowData]').each(function (index, element) { 93 94 if (index == parentThis.selectedRowIndex) { 95 $(this).attr('class', 'selected'); 96 parentThis.selectedRowData = $(this); 97 parentThis.selectedRowIndex = $('#' + parentThis.id + ' [id=listViewRowData]').index(this); 98 } 99 100 }); 101 102} 103 104~省略~ 105 106// ***************************************************************************** 107// ListViewにイベントを設定 108// ***************************************************************************** 109ListView.setListViewEvent = function () { 110 111 var parentThis = this; 112 113 $('#' + parentThis.id).children('tbody').children('[id=listViewRowData]').click(function () { 114 var clickThis = this; 115 $('#' + parentThis.id).children('tbody').children('[id=listViewRowData]').each(function (index, element) { 116 117 if (index != $('#' + parentThis.id).children('tbody').children('[id=listViewRowData]').index(clickThis)) { 118 $(element).attr('class', ''); 119 } 120 121 }); 122 $(this).attr('class', 'selected'); 123 parentThis.selectedRowData = $(this); 124 parentThis.selectedRowIndex = $('#' + parentThis.id).children('tbody').children('[id=listViewRowData]').index(this); 125 }); 126 127}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/05/07 10:20 編集
2017/05/07 10:18
2017/05/07 10:22
2017/05/07 10:23
2017/05/07 10:26
2017/05/07 10:28
2017/05/07 10:31
2017/05/07 10:33
2017/05/07 10:37
2017/05/07 10:37
2017/05/07 10:42
2017/05/07 10:44
2017/05/07 10:46