Jquery onclick函数越来越多地运行

时间:2017-03-08 13:47:22

标签: javascript jquery ajax datatables onclick

我有一个有趣的问题,我无法弄清楚为什么会这样发生。我有dataTables和数据来选择更改选择后,使用jquery ajax发布。我有onclick功能进行多项选择。 (它必须在单击表格时运行,它会改变行样式等。)我注意到了(使用调试);当我第一次加载onclick后点击行时,按预期工作一次。但是在第二次加载(选择更改后)运行2次后点击,然后在第三次加载后点击运行3次我不明白发生了什么。所以需要一些帮助。

这是加载表的选择更改函数;

// 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成功功能中创建它,但它在其他任何地方都无法工作。提前谢谢。

5 个答案:

答案 0 :(得分:3)

问题是因为每次在change上发生#groupSelect事件时,您都会触发一个AJAX请求,并且在该AJAX请求的success处理程序中,您附加另一个 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());
});

答案 1 :(得分: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数据表事件以及jQuery off :您可以将行突出显示功能放在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() + '');
          });
        }
      });
    }
  });
}

答案 2 :(得分:0)

您正在为click函数中的.change()事件添加绑定。这样,您每次都会添加一个新绑定,因此对函数的调用次数也会增加。

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

答案 3 :(得分:0)

每次调用$('selector').on('click', ...)时,您都会注册一个新的回调函数,以便在单击与您的选择器匹配的元素时执行。因此,在这种情况下,每次ajax调用完成时,您将注册另一个单击处理程序。因此,如果您的ajax调用执行了三次,您将注册三个相同的点击处理程序,并且所有这些都将执行。

您应该确保$('#questTable tbody').on('click', 'tr', ...)只执行一次。

答案 4 :(得分:0)

您在每次ajax请求后添加了新的事件侦听器, 从ajax回调中移动click事件

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