2017-03-08 190 views
1

我有一個有趣的問題,我無法弄清楚它爲什麼會這樣發生。我有數據表和數據出現在選擇變化後,用jQuery的ajax後。我有onclick功能多選。 (它必須在點擊表格時運行,它會改變行的樣式等)我注意到(與調試);當我第一次加載onclick之後點擊行,按預期工作一次。但點擊後第二次加載(選擇更改)它運行2次並點擊後第三次加載它運行3次我不明白髮生了什麼事情。所以需要一些幫助。jquery onclick函數多次運行多次

這是加載表格的選擇更改功能;

// in doc.ready 
$('#groupSelect').change(function() { 
    var group = $('#groupSelect').val(); 

    if (!$.fn.DataTable.isDataTable('#questTable')) //this is for first load 
    { 
    GetQuestions(group); 
    } else //this is for after first load 
    { 
    var table = $('#questTable').DataTable(); 
    table.destroy(); 
    table.clear().draw(); 
    GetQuestions(group); 
    } 
}); 

而這是獲取數據的GetQuestions()函數;

// out of doc ready 
function GetQuestions(questGroup) { 
    $.ajax({ 
    type: 'POST', 
    dataType: 'json', 
    contentType: 'application/json', 
    url: 'SetAudit.aspx/Questions', 
    data: '{"q_group":"' + questGroup + '"}', 
    success: function(result) { 
     $('#questTable').DataTable({ 
     data: result.d, 
     columns: [{ 
      data: 'q_id' 
     }, { 
      data: 'q_text' 
     }] 
     }); 


     //this click function runs multiple time at 1 click 
     $('#questTable tbody').on('click', 'tr', function() { 
     var table = $('#questTable').DataTable(); 
     var count = table.rows('.selected').count(); 
     $(this).toggleClass('selected'); 
     $('#selectedCount').text('' + table.rows('.selected').count() + ''); 
     }); 
    } 
    }); 
} 

我不這樣做,如果它可以在ajax成功func中創建它,但它不能在其他地方工作。提前致謝。

回答

3

的問題是,因爲每次change事件上#groupSelect發生你開除一個AJAX請求,並在success處理程序,AJAX請求您將另一click事件處理程序表的tr。因此它們重複。

爲了解決這個問題,我建議你將tr事件處理程序移動到success處理程序之外,並且只在DOM負載時運行一次。試試這個:

function GetQuestions(questGroup) { 
    $.ajax({ 
     type: 'POST', 
     dataType: 'json', 
     contentType: 'application/json', 
     url: 'SetAudit.aspx/Questions', 
     data: { q_group: questGroup }, 
     success: function (result) { 
      $('#questTable').DataTable({ 
       data: result.d, 
       columns: [ 
        { data: 'q_id' }, 
        { data: 'q_text' } 
       ] 
      }); 
     } 
    }); 
} 

// do this on load *only* 
$('#questTable tbody').on('click', 'tr', function() { 
    var table = $('#questTable').DataTable(); 
    var count = table.rows('.selected').count(); 
    $(this).toggleClass('selected'); 
    $('#selectedCount').text(table.rows('.selected').count()); 
}); 
+0

是的,先生我不喜歡在開始時使用這個函數在ajax成功。但是當我在外面創建它時(比如你的回答)它不會運行。我認爲我的真正問題是這樣的。這onclick不在其他地方工作。我能做什麼? –

+0

更改事件處理程序簽名:http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements –

+0

聽起來好像'#questTable tbody'在加載時可能不在DOM中。嘗試將其更改爲'$(document).on(...' –

0

您將在.change()函數中添加對click事件的綁定。這樣你每次都添加一個新的綁定,因此調用函數的次數越來越多。

正確的方法是將$('#questTable tbody').on('click', 'tr', function() {移到GetQuestions之外。

+0

是的,你說得對後添加新的事件監聽器。我真的嘗試過,但除了ajax調用之外,我無法在其他任何地方觸發onclick,但是現在我明白了爲什麼我不能用McCrossan的建議解決問題。謝謝你的答案。 –

1

這應該工作

//this click function runs multiple time at 1 click 
$('#questTable tbody').off().on('click', 'tr', function() { 
    var table = $('#questTable').DataTable(); 
    var count = table.rows('.selected').count(); 
    $(this).toggleClass('selected'); 
    $('#selectedCount').text('' + table.rows('.selected').count() + ''); 
}); 

有多種方法可以解決這個問題。

刪除和添加表格DOM元素:這取決於您構建數據表的方式。如果你只是從JS構建你的數據表,那麼你可以採用這種方法。

// in doc.ready 
$('#groupSelect').change(function() { 
    var group = $('#groupSelect').val(); 

    if (!$.fn.DataTable.isDataTable('#questTable')) {// this is for first load 
    GetQuestions(group); 
    } else {//this is for after first load 
    var table = $('#questTable').DataTable(); 
    table.destroy(); 
    table.clear().draw(); 
    // empty the table which will eventually clear all the event handlers 
    $('#questTable').empty(); 
    GetQuestions(group); 
    } 
}); 

使用drawCallback事件DataTable的使用jQuery off一起:您可以打電話$('selector').on('click', ...)每次放置行突出功能drawCallback

//out of doc ready 
function GetQuestions(questGroup) { 
    $.ajax({ 
    type: 'POST', 
    dataType: 'json', 
    contentType: 'application/json', 
    url: 'SetAudit.aspx/Questions', 
    data: '{"q_group":"' + questGroup + '"}', 
    success: function(result) { 
     $('#questTable').DataTable({ 
     data: result.d, 
     columns: [{ 
      data: 'q_id' 
     }, { 
      data: 'q_text' 
     }], 
     drawCallback: function(settings) { 
      //this click function runs multiple time at 1 click 
      $('#questTable tbody').off().on('click', 'tr', function() { 
      var table = $('#questTable').DataTable(); 
      var count = table.rows('.selected').count(); 
      $(this).toggleClass('selected'); 
      $('#selectedCount').text('' + table.rows('.selected').count() + ''); 
      }); 
     } 
     }); 
    } 
    }); 
} 
+0

我一直在努力當你提供答案的第二部分時,使用它我不能解決這個問題,但是現在,我知道了它的原因,並且我已經用McCrossan的建議解決了這個問題,謝謝你這個有用的和詳細的答案。 –

0

,你註冊一個新的回調執行當與你的選擇器匹配的元素被點擊時。因此,在這種情況下,每當Ajax呼叫完成時,您將註冊另一個點擊處理程序。因此,如果您的ajax調用執行三次,您將註冊三個相同的點擊處理程序,並且它們都將執行。

你應該確保你的$('#questTable tbody').on('click', 'tr', ...)只執行一次。

+0

是的,你是對,除了ajax調用之外,我無法在其他任何地方觸發onclick,但現在我明白了爲什麼我不能用McCrossan的建議來解決問題,謝謝你的回答。 –

0

你有充分的Ajax請求, 移動click事件從Ajax回調

//out of doc ready 
 
function GetQuestions(questGroup) { 
 
\t $.ajax({ 
 
\t \t type:'POST', 
 
\t \t dataType:'json', 
 
\t \t contentType:'application/json', 
 
\t \t url:'SetAudit.aspx/Questions', 
 
\t \t data: '{"q_group":"' + questGroup + '"}', 
 
\t \t success: function (result) { 
 
\t \t \t $('#questTable').DataTable({ 
 
\t \t \t \t data: result.d, 
 
\t \t \t \t columns: [ 
 
\t \t \t \t \t { data: 'q_id' }, 
 
\t \t \t \t \t { data: 'q_text' } 
 
\t \t \t \t ] 
 
\t \t \t }); 
 

 

 
\t \t } 
 
\t }); 
 
} 
 

 
//this click function runs multiple time at 1 click 
 
$('#questTable tbody').on('click', 'tr', function() { 
 
\t var table = $('#questTable').DataTable(); 
 
\t var count = table.rows('.selected').count(); 
 
\t $(this).toggleClass('selected'); 
 
\t $('#selectedCount').text('' + table.rows('.selected').count() + ''); 
 
});

+0

我確實嘗試了這個,但現在我得到了真正的問題並解決了它與McCrossan的建議,但謝謝你的答案。 –