JavaScript网页停止运行,无响应/崩溃

时间:2019-08-24 10:34:10

标签: javascript html html5-canvas

我在执行Javascript分配任务时遇到问题。实质上,我要完成的工作是使用html5 canvas的“屏幕保护程序”设计循环。当在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

2 个答案:

答案 0 :(得分:0)

您当前的代码基本上是通过调用 echo $this->Html->image("/images/loader/loader.gif", array("alt" => "", 'class' => 'loader', 'id' => 'ajximg2', 'style' => 'display:none')); echo $this->Form->input('item_id', array('label' => 'Competition Name', 'empty' => '-----Select-----', 'id' => 'item')); controller: public function event_item_ajax($eventId) { $items = $this->Item->find('list', array('conditions' => array('Item.event_id' => $eventId))); $this->set('items', $items); } Jquery: $(function() { $( "#event").change(function( event ) { $("#ajximg2").show(); alert($(this).val()); $.ajax({ url: '/results/event_item_ajax/' +escape( $(this).val()), cache: false, type: 'GET', dataType: 'HTML', success: function (html) { $("#item").html(html); $("#ajximg2").hide(); }, }); }); }); 向事件循环发送垃圾邮件。

screenloop()仅在1.5秒内安排对该函数的调用,但直到那时才保持循环。因此,基本上,您的循环只会填满事件循环,直到浏览器崩溃为止。

setTimeout()

对于像您这样的动画,您可能需要查看requestAnimantionFrame()。在非常粗略的第一次尝试中,它看起来可能是这样的(我并没有看过您的所有代码,无论它是否真的可以工作。取决于不同的因素,例如每个渲染循环需要多长时间等):

function screenstart(){
    loop = 1;
    while (loop = 1){
        setTimeout(screenloop(), 1500);
        screenloop();
    }
}

答案 1 :(得分:0)

正如我在评论中所说,问题出在您的screenstart函数中。实际上确实有很多错误,但是导致浏览器崩溃/冻结的主要原因是循环实际上从未结束。 Javascript是单线程的,即一次只能执行一件事-并且循环应该在loop为0时停止(或者如果您正确使用了==而不是{{1 }}),这永远不会发生,因为您的代码被困在一个循环中,不断执行=(同时以后还要调度对该函数的越来越多的调用,因为它永远无法到达它们)。

尽管有一个简单的解决方法。将该功能缩减为:

screenloop

然后在function screenstart(){ loop = 1; setInterval(screenloop, 1500); } 中执行以下操作:

screenloop

最重要的区别是,您只需安排function screenloop(){ if (loop == 1) { randcal(); ifstatements(); } } 每1.5秒运行一次,同时允许其他事件发生,并在必要时运行其他代码。包括将screenloop设置为0的可能性。每次loop运行时,它都会检查该值,并且只有在该值为1时才进行填充。