javascript - Javascript 网页停止运行、无响应/崩溃
问题描述
我遇到了 Javascript 分配任务的问题。基本上我想要完成的是使用 html5 画布的“屏幕保护程序”设计循环。当在 html 中单击一个按钮时,它会运行一个函数,该函数使用随机数生成来决定形状、形状的位置、形状填充颜色和形状描边样式,绘制形状然后再次循环。我目前遇到的问题是单击按钮时,页面(我同时使用 chrome 和 firefox)崩溃。我知道这可能是因为我正在使用循环,所以作为响应,我在函数上延迟了 1.5 秒——但它仍然无法运行。任何有关如何改进这一点的建议将不胜感激。
谢谢 :)
(我尝试将代码缩进 4 个空格,抱歉由于某种原因不起作用..?)
HTML:
<button onclick="Screensaver()">Screensaver</button><br>
<div id="Screensaver">
<br><button onclick="screenstart()">Start Screensaver</button><br>
<br><button onclick="screenstop()">Stop Screensaver</button>
</div><br>
<canvas id="myCanvas" width="1000" height="600" style="border:1px solid #47bfff;">
</canvas>
JAVASCRIPT:
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var gradient=ctx.createLinearGradient(0,0,canvas.width,0);
//screensaver variables
var loop = 0;
var shapenum = 0;
var fillnum = 0;
var stylenum = 0;
var SS = document.getElementById("Screensaver");
//rectangle
var rectx1 = 0;
var recty1 = 0;
var rectx2 = 0;
var recty2 = 0;
//triangle
var trix = 0;
var triy = 0;
//circle
var circx = 0;
var circy = 0;
var circr = 0;
//radius calculation
var sct = 0;
var scb = 0;
var scl = 0;
var scr = 0;
var scmax = 0;
//SCREENSAVER FROM HERE
SS.style.display = "none";
function Screensaver() {
if (SS.style.display === "" +
"none") {
SS.style.display = "block";
} else {
SS.style.display = "none";
}
}
//loop
function screenstart(){
loop = 1;
while (loop = 1){
setTimeout(screenloop(), 1500);
screenloop();
}
}
function screenstop(){
loop = 0;
}
function screenloop(){
randcal();
ifstatements();
}
//just calculations from here on down
解决方案
正如我在评论中所说,问题出在你的screenstart
功能上。实际上有很多错误的地方,但导致浏览器崩溃/冻结的主要问题是循环永远不会真正结束。Javascript 是单线程的,也就是说它一次只能做一件事 - 而循环应该在loop
0 时停止(或者如果你正确使用==
而不是=
),这永远不会发生,因为你的代码卡在一个循环中,screenloop
不断执行(同时还安排了越来越多的对该函数的调用,而不是它可以到达它们)。
不过有一个简单的解决方法。将功能缩减为:
function screenstart(){
loop = 1;
setInterval(screenloop, 1500);
}
然后在中执行以下操作screenloop
:
function screenloop(){
if (loop == 1) {
randcal();
ifstatements();
}
}
最重要的区别是您只需安排screenloop
每 1.5 秒运行一次,同时允许其他事件发生,并在必要时允许其他代码运行。包括loop
设置为 0 的可能性。每次screenloop
运行时,它都会检查这个值,并且只有当值为 1 时才会执行它的工作。
推荐阅读
- go - 有没有办法优化该代码?Go中的TCP服务器
- testing - 登录到应用程序后的 TestCafe 测试引发错误 401 未经授权
- ruby-on-rails - Rails 路由到未知页面与 ActiveStorage 图像路径混淆
- java - Travis CI - Travis(401 和 400)测试失败,但在本地运行 Java Spring Boot
- apache - Can't Apache2 start errr: 找不到 SOAP/Transport/HTTP.pm
- javascript - 加载文档时,如何阻止 Safari 将注意力集中在标有用户名或密码的表单字段上?
- scrapy-splash - 飞溅经常以状态码 520 下降
- html - 如何将单选按钮值作为数字获取
- c# - 在每个用户输入中都有一个控制台命令
- python - 为什么代码不会写在记事本文件中?