jQuery 中 $.cache 的用途是什么?

发布于 2025-01-06 01:15:20 字数 353 浏览 0 评论 0原文

我看到通过 .on() 注册的事件处理程序保存在 $.cache 中。 我还看到事件处理程序也保存在 $(elem).data() 中。

$.cache 中保存的对象指的是注册事件的 DOM 节点。当 DOM 节点分离时,这会导致内存泄漏,从而强制调用 .off()

我遇到的情况是,我不知道 DOM 节点(我附加了事件处理程序)何时被分离。虽然我可以在代码中保留对该 DOM 节点的引用并调用 .off() 进行清理,但这看起来不太好,因为要知道 DOM 节点何时被删除并不容易已删除。

最好的方法是什么?

I see that the event handlers registered through .on() are held in $.cache.
I also see that the event handlers are also held in $(elem).data().

The objects held in $.cache refer to the DOM nodes on which the events are registered. This leads to memory leak when the DOM nodes are detached, and this makes .off() calls mandatory.

I have a situation where I don't know when the DOM node (to which I attached the event handler) is being detached. While I can hold the reference to that DOM node in my code and call .off() to clean up, it doesn't seem nice, because it is not straightforward to know when the DOM node is being removed.

What is the best way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

羅雙樹 2025-01-13 01:15:21

我遇到过类似的情况,使用 Knockout 在文档中添加和删除 dom 树。然而,jquery 用于将事件侦听器附加到这些 dom 树。当剔除从文档中删除 dom 元素时,侦听器不会解除绑定,因此 dom 树永远不符合垃圾回收的条件。我们添加了一个清理函数,每次哈希更改时都会遍历 jquery $.cache,甚至找到绑定到不在文档中的 dom 树的处理程序。然后它会解除侦听器的绑定,从而使 dom 树符合垃圾收集的条件,并修复我们所看到的大部分泄漏,即应用程序的往返行程过去会泄漏 13MB,现在进行这些更改后,它仅泄漏 3MB。

for (var i in $.cache) {
            if ($.cache.hasOwnProperty(i)) {

                if ($.cache[i].handle && $.cache[i].handle.elem && document !== $.cache[i].handle.elem && !jQuery.contains(document, $.cache[i].handle.elem)) {
                    //we have an event handler pointing to a detached dom element!
                    //this is a memory leak as this detached dom element cannot be garbage collected until
                    //all references to it are removed. So lets delete the event handler to get memory back!
                    var orphan = $($.cache[i].handle.elem);
                    $('body').append(orphan);
                    orphan.off();
                    orphan.remove();
                    orphan = null;
                }
            }
        }

I ran in to a similar situation where Knockout is used to add and remove dom trees from the document. However, jquery is used to attach event listeners to these dom trees. When knockout removes dom elements from the document the listeners are not unbound so the dom tree is never eligible for garbage collection. We have added a clean up function that trawls through the jquery $.cache everytime the hash changes and finds even handlers that are bound to dom trees that are not in the document. It then unbinds the listeners thus making the dom tree eligible for garbage collection and fixing most of the leaks that we are seeing i.e. round trip round the app used to leak 13MB now it leaks just 3MB with these changes in place.

for (var i in $.cache) {
            if ($.cache.hasOwnProperty(i)) {

                if ($.cache[i].handle && $.cache[i].handle.elem && document !== $.cache[i].handle.elem && !jQuery.contains(document, $.cache[i].handle.elem)) {
                    //we have an event handler pointing to a detached dom element!
                    //this is a memory leak as this detached dom element cannot be garbage collected until
                    //all references to it are removed. So lets delete the event handler to get memory back!
                    var orphan = $($.cache[i].handle.elem);
                    $('body').append(orphan);
                    orphan.off();
                    orphan.remove();
                    orphan = null;
                }
            }
        }
眼眸印温柔 2025-01-13 01:15:20

“执行此操作的最佳方法是什么?”

如果您要使用 jQuery,则必须使用其 API 来删除元素,并且必须使用正确的方法,否则,正如您所说,您将出现内存泄漏。

如果您不知道 DOM 节点何时被删除,并且它是否导致泄漏,我认为这意味着您正在使用另一个库和 jQuery。正是因为这个原因,这不是一个好主意。

您需要确保任何受 jQuery 影响的元素都会被 jQuery 删除。 $.cache 中还存储了一些您未明确设置的数据。这意味着应该使用 jQuery 删除所有元素,而不仅仅是那些认为可能有数据的元素。


“jQuery 中 $.cache 的用途是什么?”

将处理程序和其他数据与元素关联起来。数据和元素之间的链接基本上是存储在元素的 Expando 属性上的序列号。

如果您在没有 jQuery 的情况下删除元素,则 $.cache 中的关联数据将被孤立。

这种方法的目的是防止潜在的泄漏。不幸的是,它可能会造成更严重的泄漏。

"What is the best way to do this?"

If you're going to use jQuery, you must use its API for removing elements, and you must use the proper methods, otherwise, as you stated, you'll have memory leaks.

If you don't know when the DOM node is being removed, and if it is causing a leak, I'd assume this means that you are using another library alongside jQuery. That's just not a good idea for this very reason.

You need to ensure that any elements affected by jQuery are removed by jQuery. There's also some data stored in $.cache that you didn't explicitly set. This means that all elements should be removed with jQuery, instead of just those that you think may have data.


"What is the purpose of $.cache in jQuery?"

To associate handlers and other data with elements. The link between the data and the elements is basically a serial number stored on an expando property on the element.

If you remove the element without jQuery, the associated data in $.cache is orphaned.

The purpose of this approach was to prevent potential leaks. Unfortunately it potentially creates more severe leaks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文