一段时间后页面变得无响应

Page becomes unresponsive after some time

我的 jQuery/Javascript 代码有问题。一切都按预期工作,但一段时间后页面变得无响应并抛出 jQuery 的 Unresponsive Script 错误。 我正在使用 jQuery Library 将列表显示为封面流。

此外,在所有后端调用之后,我必须刷新特定的 div,因此每次调用后端时我都会销毁并重新创建 div。

请告诉我下面给出的代码结构有什么问题:

(请注意,这只是一个重要方法的片段,所有这些方法中还写有其他逻辑,此处未显示)。

function showAllData(dataFromServer) {
  $('#child').remove();
  $('#parent').append($('<div id="child"></div>'));

  $.each(dataFromServer.someArray, function(index, item) {
    var html = '<li>' + item + '</li>';
    $('#child').append($(html));
  });

  //Attach Event to div
  $("#child").on("click", function() {
    removeTag();
  });
};

$(document).ready(function() {
  //got data from server(Spring MVC) in a var 'dataFromServer'
  //code not written here
  showAllData(dataFromServer);
  $("#child").flipster(); //a coverflow library 
});


$(document).on('submit', '#formSubmit', function(event) {
  event.preventDefault();
  $.ajax({
    url: url,
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    async: true,
    cache: false,
    data: JSON.stringify({
      dataFromClient: dataFromServer
    }),
    type: "POST",
    success: function(data) {
      dataFromServer = data;
      showAllData(dataFromServer);
      $("#child").flipster();
    },
    error: function(xhr, status, error) {
      console.log(xhr.responseText);
    }
  });
  return false;
});

function removeTag() {
  $.ajax({
    url: 'deleteBooks',
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    async: true,
    cache: false,
    data: JSON.stringify({
      keyword: tag,
      dataFromClient: dataFromServer
    }),
    type: "POST",
    success: function(data) {
      dataFromServer = data;
      showAllData(dataFromServer);
      $("#child").flipster();
    },
    error: function(xhr, status, error) {
      console.log(xhr.responseText);
    }
  });
};

有什么想法吗?

[编辑]:在移动设备上访问网站时会很快发生这种情况。页面卡住了!但是在桌面版本上工作时,页面在一段时间后变得无响应并抛出 Maximum Call Stack Size Reached 错误。

这可能是因为智能手机的内存。尽管如此,两个版本都存在问题。

您正在进行一些递归,它以指数方式添加 #child .click() 处理程序。我制作这个 jsFiddle 是为了简化您的代码并演示正在发生的事情。打开控制台,单击 'submit' 开始,然后在其中一个列表项上单击几次。您会看到每次点击,控制台都会输出越来越多的行。

尝试将 $("#child").on("click"...){} 移到 function showAllData(){}

之外

更新: 为了让处理程序在您删除并重新添加 #child 后工作,您可以像这样添加点击侦听器:

$('#parent').on('click', '#child', function() {
    // 
});

我已将其放入更新后的 jsFiddle

更新 2: 我看到刷新后 Flipster 没有重新初始化 #child 并想出了这个:

$("#child").flipster(); 更改为 $("#parent").flipster();。然后在 showAllData() 中执行 $('#child').remove() 之后:

// remove the flipster classes from #parent or flipster will not re-initialise when called next time.
$('#parent').removeClass('flipster').removeClass(function(index, css) {
    return (css.match(/(^|\s)flipster-\S+/g) || []).join(' ');
});

我把这个放在 codePen.