我制作了一个自定义函数来复制setInterval函数。 这是我正在尝试做的事情:
<html>
<head>
<script id='scpt_a'>
//custom setInterval function
function interval(func,ti){
try{
func.call(null);
}
catch(err){
throw new Error(err.toString());
}
setTimeout(()=>{interval(func,ti); },ti);
}
//custom setinterval function end
$('#start).click(()=>{
$('body').append("<script id='scpt_b'>interval(()=>
{console.log('hello');},10000);</script>");
});
$('#stop).click(()=>{
$('#scpt_a').remove();
$('#scpt_b').remove();
});
</script>
</head>
<body>
<button id='start'>start</button>
<button id='stop'>stop</button>
</body>
</html>
无论何时运行此代码,它都可以正常工作,即当我单击开始按钮时,它会附加代码,以便代码执行并继续打印 你好 。现在,当我按下停止按钮时,它会删除 附加脚本以及初始(非附加)脚本 。因此,由于该脚本不存在,因此应该停止执行,但不会发生。
我使用了 chrome开发工具,在该工具中,点击停止按钮后,我发现没有脚本( ),但仍在控制台上打印 你好 。
请帮助我弄清楚为什么会这样以及如何解决此问题。
答案 0 :(得分:3)
将一些脚本添加到页面时,浏览器会对其进行解析。以后删除脚本标记时,没关系,脚本已经被解析,处理并且位于浏览器内存中。因此,即使您从页面中删除了脚本标签,您的interval
函数也将继续运行。
以下是此事实的说明。我添加了对jQuery的引用,看到了第一个警报,然后将其删除,然后删除了jQuery脚本标签,您可以看到我仍然可以使用jQuery $
函数:
<script id="s1" src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script>
alert($);
$("#s1").remove();
alert($);
</script>
答案 1 :(得分:1)
正如xxxmatko的答案中已经指出的那样,假设已对其进行解析,则从DOM中删除脚本元素不会阻止其运行。
您需要提出另一种解决方案来取消间隔的执行。也许最简单的方法是使用标准的setInterval
函数。可以这样完成:
// Start the interval:
let intervalID = setInterval(function() { /* your code */}, 10000);
// Stop the interval:
clearInterval(intervalID);
但是,如果您坚持使用自定义间隔功能(例如您的示例中的功能),则可以实现一些功能,以类似的方式在以后取消间隔。例如,您可以在时间间隔函数中检查条件:
function interval(func,ti){
/* your code */
if ( /* some condition */ )
setTimeout(()=>{interval(func,ti); },ti);
}
当单击$('#start')
或$('#stop')
时,此条件分别设置为true或false。
此外,这两种解决方案都避免了代码中的另一个问题:如果用户单击$('#start')
两次,您将在DOM中最终得到两个脚本元素(具有相同的ID!)。 / p>