我在执行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
答案 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时才进行填充。