最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Jquery onclick function runs multiple time increasingly - Stack Overflow

programmeradmin0浏览0评论

I have interesting problem and i can't figure it out why it's happening like that. I have dataTables and data es after selection change on a select, with jquery ajax post. And i have onclick function for multiple selection. (It must be run when click at table and it changes rows style etc.) I noticed that (with debug); when i click on row after first load onclick works one time as expected. But click after second load (selection changed) it runs 2 time and click after third load it runs 3 time i don't understand what's going on. So need some help.

Here is selection change function that loads the table;

// 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);
  }
});

And this is GetQuestions() function that gets data;

// 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() + '');
      });
    }
  });
}

I don't if it is ok that i created it in ajax success func but it doesn't work anywhere else. Thanks in advance.

I have interesting problem and i can't figure it out why it's happening like that. I have dataTables and data es after selection change on a select, with jquery ajax post. And i have onclick function for multiple selection. (It must be run when click at table and it changes rows style etc.) I noticed that (with debug); when i click on row after first load onclick works one time as expected. But click after second load (selection changed) it runs 2 time and click after third load it runs 3 time i don't understand what's going on. So need some help.

Here is selection change function that loads the table;

// 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);
  }
});

And this is GetQuestions() function that gets data;

// 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() + '');
      });
    }
  });
}

I don't if it is ok that i created it in ajax success func but it doesn't work anywhere else. Thanks in advance.

Share Improve this question edited Mar 8, 2017 at 14:00 Gangadhar Jannu 4,4546 gold badges32 silver badges53 bronze badges asked Mar 8, 2017 at 13:47 FlardrynFlardryn 4871 gold badge11 silver badges27 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 4

The issue is because every time a change event occurs on #groupSelect you fire an AJAX request, and in the success handler of that AJAX request you attach another click event handler to the tr of the table. Hence they duplicate.

To fix this I'd suggest you move the tr event handler outside the success handler and only run it once on load of the DOM. Try this:

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());
});

This should work

 //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() + '');
});

There are multiple ways you can solve the issue.

Removing and Adding the table DOM element: It depends on the way you construct data table. If you are constructing your datatable only from JS then you can go with this approach.

// 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);
  }
});

Using drawCallback event of datatable along with jQuery off: You can place the row highlighting function in 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() + '');
          });
        }
      });
    }
  });
}

You're adding the binding to the click event inside your .change() function. This way you add a new binding everytime, hence the increasing number of calls to the function.

The proper way to do so is moving $('#questTable tbody').on('click', 'tr', function () { outside of GetQuestions.

Every time you call $('selector').on('click', ...), you're registering a new callback to execute when an element matching your selector is clicked. So in this case, every time that ajax call pletes, you will register another click handler. So if your ajax call executes three times, you will have registered three identical click handlers, and all of them will execute.

You should make sure your $('#questTable tbody').on('click', 'tr', ...) is only executed once.

You have add new event listener after every ajax request, move click event from ajax callback

//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() + '');
});

发布评论

评论列表(0)

  1. 暂无评论