【问题标题】:remove JS functions and events from memory after removing the JS code from HTML从 HTML 中删除 JS 代码后,从内存中删除 JS 函数和事件
【发布时间】:2020-02-11 20:13:02
【问题描述】:

我有一个有很多弹出窗口的网站,每当用户加载弹出窗口(通过 ajax)时,弹出窗口中也会加载一个 JavaScript 代码,我希望在删除它的弹出窗口时删除这个 JavaScript 代码。

主站代码:

<body>

...

<div id="popup" style="display:none">

</div>
...

</body>

然后是js文件中的加载器:

$.ajax('url',{
    success:function(data){
        $("#popup").show().html(data);
    };
});

ajax 调用的视图之一并将其推送到弹出窗口中:

 some html codes
<script>
$(document).on('click',function(){
console.log("document click");
});
</script>

当用户关闭弹出窗口时,我使用此代码清空弹出窗口:

$("#popup").hide().html("");

但这并没有结束加载的on click事件,视图中的任何函数都将仍然存在于内存中并且可以被调用!

这是一个问题,因为我这里有很多弹出窗口,并且 JavaScript 会在一段时间后占用内存,所以我需要在使用网站一段时间后刷新浏览器,而且每次重新加载弹出窗口时都会重复事件!

如果无法从内存中清除这些JS,有什么解决方法吗?

【问题讨论】:

  • $(document).off('click'); ?? - (api.jquery.com/off),对于通过ajax 加载的脚本,给它一个id 并在脚本元素上使用.remove(),但您仍然需要删除event handlers
  • 这能回答你的问题吗? Best way to remove an event handler in jQuery? 连同这个用于删除脚本 (stackoverflow.com/questions/30072887/…)
  • @RyanWilson 感谢您的参考,但不,它不能回答问题。你看,问题不仅在于事件,还在于 ajax 请求附带的所有内容,我不希望函数在弹出窗口关闭或事件后保留
  • 正如我所说,在我给你的第二个链接中,给 scriptid 并删除它,因此 functions
  • 我显然误解了您要完成的工作,简短的回答是,如果不刷新页面或导致回发,就无法从内存中删除动态脚本加载的函数,但是您可以由于缺少更好的词 "destroy" 通过将事物设置为 undefined 等等,动态脚本中的所有内容,这必须通过您在删除部分视图时调用的清理或卸载函数来完成,也许是已接受的回答这篇文章 (stackoverflow.com/questions/34997399/…) 会让你继续前进。

标签: javascript jquery garbage-collection


【解决方案1】:

我从你的问题中得到的(如果我理解正确的话)是你需要一种方法来使用一些事件监听器从未使用的函数(也可能是变量)中清理你的内存,这是我的方法:

#1 - 使用removeEventListener

removeEventListener 是一种用于从 事件目标 中删除不需要的事件侦听器的方法,例如:

// add click event to the body
document.body.addEventListener('click', function clickHandler(){
   console.log("document click");
});

// remove click event from the body
document.body.removeEventListener("click", clickHandler)

#2 - 垃圾回收

JavaScript 没有提供直接的方法来清除内存中不必要的数据(函数声明或变量声明),但我们可以使用垃圾收集来欺骗它。 垃圾收集使用一种算法从内存中清除不必要的数据,称为Mark and Sweep。基本上,该算法通过标记所有无法通过 root 节点(JavaScript 中的 global 对象)访问的节点(对象)来清理内存,并将它们从内存中删除。我们可以通过使用两个东西(IIEF 和 Block-Scoping)来利用这一点。

IIFE

IIFE立即调用函数表达式的首字母缩写词。如果您更深入地了解 IIFE,您会发现在 (...) 中创建的函数隐藏在 global 范围之外的不同范围中,这意味着通过将函数创建为 IIFE,我们将阻止 global 对象从访问它意味着它会在执行后被 Garbage Collector 从内存中删除。

看看这个例子:

(function foo() {
   // your code goes here
})()

console.log(foo) // ReferenceError: foo is not defined

块作用域

Introduction to Scope

块语句用于对零个或多个语句进行分组。该块由一对大括号 {...} 分隔,并且可以选择标记。

如果您使用letconst 关键字在其中声明变量,则global 对象将无法访问您的变量,然后可以通过垃圾收集器 从内存中删除> 在它被执行之后。

看看这个例子:

function foo(data) {
   // do something with the data
}

{
   let someBigData = []
   foo(someBigData)
}

console.log(someBigData) // ReferenceError: someBigData is not defined

【讨论】:

    猜你喜欢
    • 2012-03-16
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 2017-05-18
    • 2018-03-18
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    相关资源
    最近更新 更多