Javascript 事件和DOM元素

Javascript 事件和DOM元素,javascript,jquery,javascript-events,Javascript,Jquery,Javascript Events,让我们假设我有一个具有两列布局的页面,其中左列是一组链接,当单击该链接时,它会在右列中加载关联的html页面/模板 加载模板时,有一个模板处理程序通过requirejs初始化为单例,它定义了一些方法和处理程序,如: SomePage.prototype.saveHandler: function(e) { ... }; // Page handler has a handler SomePage.prototype.initialize: function() { $('#btnSav

让我们假设我有一个具有两列布局的页面,其中左列是一组链接,当单击该链接时,它会在右列中加载关联的html页面/模板

加载模板时,有一个模板处理程序通过requirejs初始化为单例,它定义了一些方法和处理程序,如:

SomePage.prototype.saveHandler: function(e) { ... }; // Page handler has a handler

SomePage.prototype.initialize: function() {
    $('#btnSave').on('click', saveHandler);
}
然后,每次加载页面时,我都通过初始化方法附加DOM事件

SomePage.initialize(); // This attaches the click event
现在,当我单击左侧的另一个链接时,将加载一个不同的模板页面,并对该页面重复上述过程

我想知道先前附加到btnSave元素的click事件会发生什么变化?它现在是jQuery缓存中的悬空事件处理程序吗

如果我尝试在再次加载同一页面时删除它,它是否真的会删除原始事件

$('#btnSave').off('click', saveHandler);
执行以下块是否可以防止内存泄漏/挂起引用

// The potential problem here is that btnSave is part of the newly loaded template 
// and not the element i attached the handler to earlier (which doesn't exist anymore)
$('#btnSave').off('click', saveHandler);

$('#btnSave').on('click', saveHandler); 

什么是确保我最终不会出现悬空引用和内存泄漏的最佳方法。对于普通javascript来说,这也是一个潜在的问题。我的理解是,当刷新模板页面时,上述操作将不起作用。我将在这段时间内进行试验,但如果能知道专家们是如何处理的,那就太好了。谢谢

加载新的tmpl时,只需为此附加事件。例如:


$(“#btnSave”、$(newy#tmpl))。在(“单击”、…

上,查看javascript大师Andy Osmani的这张幻灯片。您将在此处找到有关内存泄漏和循环引用的答案:

在加载模板后,您应该将单击功能附加到按钮运行时,而不是将单击事件附加到按钮

var element = $("<div id='tempDiv' class='main_container o-hidden'><button value='Click' id='btnSave'/></div>");

$("#btnSave",element).each(function(){
    $(this).attr("onclick","tryMe();");
});
var元素=$(“”);
$(“#btnSave”,元素)。每个(函数(){
$(this.attr(“onclick”,“tryMe();”);
});

它会将tryMe click函数附加到您的按钮上,元素变量应根据模板内容创建。

为什么不简单地将其设置为委托事件,并只注册一次:

$( ".someParentThatsAlwaysOnPage #btnSave" ).on( "click", function() {
  var somePage = getMeContextOfProperObject();
  somePage.saveHandler();
});

这样,click事件只绑定一次,jQuery将随着DOM的更改而更新侦听器范围。您所需要做的就是提供一种获取适当对象的方法。在没有看到更多代码的情况下,我无法在这方面帮助您。

我肯定会使用
关闭
,然后再使用
打开
,就像您所做的那样。但是有什么可能吗在重新加载模板之前关闭
是一种可行的方法吗?我认为该模式是一种解决方案,但我不确定是否需要它,因为jQuery可能在内部处理它。如果每个页面实现了一个接口,并在加载时注册为当前页面,那么全局链接处理程序可以执行以下操作app.cache.currentPage.cleanup(),其中可能包含所有Off。我认为您是正确的,因为它不这样做会创建一个ghost元素…我认为当元素被释放时,附加的事件也会被释放。因此,如果单击任何链接替换绑定click事件的HTML元素,则不需要“Off”jQuery可能会使用WeakMap来实现这样的事情,因此如果元素消失,它们将被GCed。谢谢!Save只是一个例子。大多数页面都会根据其内容使用不同的事件侦听器。您的建议很好,但它只在每个页面都可以实现一个接口的情况下才起作用。但是,在之所以如此,是因为页面没有一个共同的分母过去保存/取消类型的功能。谢谢发布。这太棒了!我熟悉chrome调试器中的内存工具。今天的一天,我将尝试找一些时间通过内存分析器对其进行分析,并揭开谜团。最后我要做的另一件事是研究它我认为一个简单的修复方法是引入一种功能,允许在注册事件时传递唯一标识符,并且jQuery可以在内部用新的处理程序替换现有的处理程序。