在我的 HTML/JS 应用程序中,我根据运行时的一些规则和用户操作动态生成表元素。我通过字符串添加生成表的内容,最后使用 Jquery .html() 方法将其设置为容器。 AFAIK,Jquery 可以处理自己的内存问题,并且可以比直接设置innerHTML 更好地处理一些更详细的内容。根据用户操作,在下一阶段,生成一个完全不同的表并再次设置到相同的主容器。容器保持稳定,并且容器的 html 使用新表动态更新。
我的问题是关于注册事件监听器以及处理内存泄漏和性能,因为在桌面上它运行良好,但在 IPAD 或 Android 平板电脑上,经过一些操作或一些登录/注销后,应用程序变得缓慢,有时卡住并且变得无响应,并且设备不再响应单击操作。我想到内存泄漏或性能问题,并计划使用 google chrome 进行调试,但首先我想了解设计是否存在缺陷。 我脑子里有 3 个处理事件监听器的选项,目前我使用第一个:
1.option(当前使用)
// generate whole content with string addition and set by html()
var content = '<table id="t1"><tr><td>val1</td><td>val2</td><td>vall3</td>..</table>';
content += '<script>registerListeners("t1")</script>';
$('#mainContainer').html(content);
// will be called when table is set to DOM
function registerListeners(id) {
$('#t1').find('td').bind("click",function() {
cellClicked($(this[0]);});
}
function cellClicked(domCell) { // }
正如你所看到的,在每个表上,当设置mainContainer的html后在DOM中生成表时,会调用registerListener方法,该方法会绑定(bind) 每个单元格的 cellClicked 操作。在我的应用程序中,我可以对所有可能表格的所有表格单元格使用相同的 cellClicked 操作。 我不执行任何清理(对 mainContent 调用空或调用取消绑定(bind)),当要设置新表时,我只需生成一个新表内容并直接设置为主要内容
$('#mainContent').html(newTableContent);
并再次为单元格调用 registerListeners 方法。如果要执行N次表更新,则registerListeners将被调用N次。以前的听众怎么了?可能存在泄漏或性能问题?
2.选项
我生成带有注册操作的表格单元格,而不调用任何绑定(bind)方法:
var content = '<table id="t1"><tr><td onclick='cellClicked(this)'>val1</td>..';
$('#mainContainer').html(content);
function cellClicked(domCell) { // }
同样,当要生成新表时,它是通过字符串添加并向容器调用 html() 来生成的。
3.选项(计划)
正如我在SO中看到的,最好对动态生成的元素使用on方法,我将生成表作为选项1,但不调用任何registerListener方法。即使没有表存在,我在启动时只调用了一次注册方法。
// call only once at startup
$('#mainContent').on('click','.cellclass',function() { //handle cell click
var content = '<table id="t1"><tr><td class="cellclass">val1</td><td>val2..</table>';
$('#mainContainer').html(content);
当要执行注销时,取消
$('#mainContent').off('click','.cellclass');
当我们频繁更新具有 20 列和 30-40 行的表时,您对这 3 个选项有何建议或建议不同的选项,以防止内存泄漏并跟上性能?
最佳答案
考虑您要创建多少个表格单元格。 10x10 表将需要 100 个事件处理程序。他们加起来很快。更好的选择是在包含对象上使用单个处理程序。然后,您的处理程序将确定到底是什么收到了事件并采取适当的操作。
使用 jQuery,您可以通过委托(delegate)事件来完成此操作。类似的东西
$('#mytable-container').on('click', 'td', function(e) { // event logic });
函数内的“this”是接收事件的对象 - 在本例中为“td”标签。或者您可以使用 e.target 进行进一步分析。在 TD 上使用 data-XXX 属性来保存任何特定数据也有很大帮助。 (即 data-id="my-db-id")然后您可以执行 $(this).data('id') 从事件处理程序中获取“my-db-id”值。
我在 IE6 时代也遇到过和你类似的问题,摆脱额外的处理程序对我来说很有效。但这可能不是您需要的 Elixir 。可能还会出现其他问题,但这是一个好的开始。
关于javascript - jQuery,处理表格单元格上的操作监听器,处理性能和内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34212723/