0

大量のデータを含む HTML テーブルがあります。特定のセルをクリックすると、その内容が編集インターフェイスに置き換えられます。これには、とりわけキャンセル ボタンが含まれます。

キャンセル ボタンをクリックすると、次の Javascript (少し jQuery を使用) が実行されます。

function undo_changes(el) {

  // Restore the previously-stored original innerHTML and event handler
  el.innerHTML = cell_contents;
  cell_contents = undefined;
  $(el).bind('click', box_click);

  // Restore the form's action and events
  $(main_form).attr('action',main_form_destination).attr('onchange', 'return true');
}

キャンセル ボタンは次のように実装されます (this.parentNodeセルを参照)。

<button onclick="undo_changes(this.parentNode)">Cancel</button>

キャンセルボタンをクリックしても、何も変わらないように見えます。デバッガーでコードをステップ実行すると、期待どおりに変更が行われます。ただし、関数の最後に到達すると、突然すべての変更が元に戻されます。どうしたの?

Ubuntu と jQuery 1.10.2 で Chromium を実行しています。

詳細

デバッガーは、コール スタックの関数の下に次のように表示します。私はそれを理解しているふりをしません。

(function() {with (this[2]) {with (this[1]) {with (this[0]) {return function(event) {undo_changes(this.parentNode)
};}}}})

何らかの理由で、関数を終了すると、4761 行目の jQuery に実行がジャンプします。その後、jQuery は何らかの方法で関数を呼び出し、box_click()削除しようとしているものを作成します。

リクエストにより

この編集を入力すると、問題は解決しました。box_click()それにもかかわらず、編集インターフェイスを作成するを表示するように求められました。最初に質問を投稿したときのバージョンは次のとおりです。

function box_click() {
  if(cell_contents) {
    alert('Please deal with the other place you\'re editing first.');
    return false;
  }
  var id = this.id;
  var student_id = $(this).attr('student_id');
  var class_date = $(this).attr('date');
  var html = make_radio('attendance','None',get_current(this) == 'None');
  html += make_radio('attendance','Present',get_current(this) == 'Present');
  html += make_radio('attendance','Absent',get_current(this) == 'Absent');
  html += make_radio('attendance','Tardy',get_current(this) == 'Tardy');
  html += '<input type="hidden" name="student_id" value="'+student_id+'">';
  html += '<input type="hidden" name="class_date" value="'+class_date+'">';
  html += '<button onclick="undo_changes(this.parentNode)">Cancel</button>';
  cell_contents = this.innerHTML;
  var f = $(main_form);
  main_form_destination = f.attr('action');
  f.attr('action', '/classes/ajax_update_attendance/'+id+'/<?=$class_id?>').attr('onchange', 'submit(this)'); // There's a smattering of PHP on this line
  this.innerHTML = html;
  $(this).unbind('click');
}
4

2 に答える 2

0

undo_changes関数が実行されるたびに、追加のクリック イベントが要素にバインドされている状況に陥っていると思われます。これを試してみるとどうなりますか:

 $(el).unbind('click').bind('click', box_click);

これにより、現在のクリック ハンドラーのみがその要素のクリック イベントにバインドされることが保証されます。

于 2013-11-06T03:34:52.483 に答える