【问题标题】:jQuery code causing memory leakjQuery代码导致内存泄漏
【发布时间】:2012-04-12 15:37:15
【问题描述】:

以下代码导致内存泄漏(您可以看到这种情况发生的越多,越慢,越慢)。不幸的是,我无法在我的办公室下载 javascript 分析器(我可以,只需几天/几周的时间)。

这是代码,只是下拉菜单的一些简单转换:

$(document).ready(function(){
    breadcrumbOver = function () {
        $(this).stop().animate({ backgroundColor: "#3393b5", textIndent: 15 }, 250);
    }
    breadcrumbOut = function () {
        $(this).stop().animate({ backgroundColor: "#738793", textIndent: 0 }, 250);
    }
    $("nav ul li").hover(
      function () {
        $(this).children('ul.child').stop().slideDown('fast').children('li').hover(breadcrumbOver, breadcrumbOut);
      }, 
      function () {
        $(this).children('ul.child').stop().slideUp('fast').unbind(breadcrumbOver, breadcrumbOut);
      }
    );
});

任何人都可以看到可能发生内存泄漏的位置吗?

编辑:此处的实时示例 - http://rcnhca.org.uk/sandbox/(反复滚动“健康、安全和安保”,然后滚动它的孩子以查看效果,如果您快速滚入和滚出,有时动画 slideDown 不会触发够了)。

【问题讨论】:

  • 大多数时候,我们的编码方式会导致内存泄漏。
  • 您在浏览器开发者工具中看到了什么?如果您观看,您的各种动画可能会向您展示自己。你可以从中看出很多。
  • @veeTrain 我只有萤火虫,它没有显示任何异常,只是它抛出了这个错误:“WebGL:无法获得可用的 WebGL 上下文。”这与 Modernizr 不是我的脚本有关。

标签: javascript jquery memory-leaks


【解决方案1】:

问题看起来可能出在您的初始选择器中。它针对nav 下的ul 下的所有li 标签,包括所有子孙。

$("nav ul li") ...

这会导致它为nav 下的所有li 标签添加一个hover 回调,然后当您将鼠标悬停时,它会添加另一个hover 回调。

您可能希望更具体地使用它,例如专门针对直接子代。

$("nav>ul>li")

如果您有子类,您还可以使用:not(.child) 来定位所有非子类。使用 console.log(内置于 Chrome 或使用 Firebug)记录这些选择器正在拉动什么,以确保您得到您期望的结果。

【讨论】:

  • 谢谢我遵循了这个建议,但它仍在发生。如果您有兴趣,我在rcnhca.org.uk/sandbox 上放了一个活生生的例子。
  • 老实说,我没有看到这个例子有任何问题。
  • 在多次进出下拉列表的父项后,其子项上的动画变得迟缓且不稳定。
  • 不适合我。 Win7 Chrome、Fx 和 IE9 运行良好,动画非常流畅,尽管我试图欺骗它多少次。
【解决方案2】:

我明白你在说乔治;多次打开盒子后在元素之间快速滑动时效果最为明显。

也许这会影响您所看到的内容。我阅读了stop() 并觉得它可能会对您所看到的内容产生影响。您可以在stop() 中指定的第一个属性是 clearQueue。第二个同样有趣。以下是文档所说的:

clearQueue 一个布尔值,指示是否也删除排队的动画。默认为假。 jumpToEnd 一个布尔值,指示是否立即完成当前动画。默认为 false。

可能值得试一试这样的真实情况:

$(this).children('ul.child').stop(true, true)...
// (or  you want the animation to unwind, I suppose)
$(this).children('ul.child').stop(true)...

另外,我也查看了unbind,我认为你不能像你这样通过两个事件。也许您可以这样使用它而不会遇到您遇到的问题:

...unbind(breadcrumbOver).unbind(breadcrumbOut);

【讨论】:

  • 感谢 +1,您对 unbind() 的看法是正确的,但是即使我只使用 unbind(),问题仍然存在,这应该会删除所有绑定的侦听器。我还尝试了所有不同的停止参数,但它仍然变慢 =/
  • 无赖...好吧,我希望您可以依靠用户在导航到某个地方之前不要多次将鼠标悬停在上面 :-) 关于在没有参数的情况下调用unbind() 很重要。但是你不是绑定children('li'),然后解除绑定children('ul.child')吗?
猜你喜欢
  • 2012-01-18
  • 1970-01-01
  • 2017-12-05
  • 1970-01-01
  • 1970-01-01
  • 2020-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多