在for循环中的setTimeout,数组作为参数行为不端

问题描述 投票:-4回答:1

我一直致力于我的第二场比赛,其工作原理如下:

  • 有一个按钮,其位置每隔x秒随机变化一次
  • x秒由setTimeout控制
  • 每当用户点击按钮时,他们的分数增加10
  • 当得分达到30时,startGame调用Initialize,它使用JavaScript创建一个新按钮并将按钮推送到名为numOfBox的数组
  • 控件使用更新的startGame传回numOfBox,现在有两个按钮,每隔x秒更改一次上/下坐标

qzxswpoi每隔x秒多次调用该函数,而不是每x秒调用一次。如何每x秒仅调用一次该函数?

setTimeout

我更喜欢在JavaScript中而不是在ECMA5 / 6或jQuery中,或使用箭头函数。如果需要,我可以提供其余的代码。

javascript settimeout
1个回答
3
投票

我注意到你的代码存在一些问题。

  1. 你在循环中调用var box=document.getElementById('boxId'); var main=document.getElementById('Maincont'); var timeout=[]; var cnt=0; var scr=0; var levelCnt=30; var divcnt=0; var numOfbox=[]; var fcnt=0; function createDiv(Name,Width,Height,Background,Margin,Padding) { var t=t+divcnt; divcnt+=1; var Name=Name+divcnt; var Nameid='boxId'+divcnt; Name=document.createElement('button'); Name.id=Nameid; console.log('IN CREATEDIV :-'+ Nameid+':::'+Name+' cnt '+ cnt); Name.style.width=Width; Name.style.height=Height; Name.style.background=Background; Name.style.margin=Margin; Name.style.padding=Padding; Name.style.boxSizing='border-box'; Name.style.position='absolute'; Name.style.top='10px'; Name.style.left='10px'; Name.style.color='white'; Name.style.textAlign='center'; Name.style.fontSize='15px'; Name.style.textDecoration='none'; Name.style.cursor='pointer'; Name.disabled=true; t=document.createTextNode('HIT ME'); Name.appendChild(t); Name.addEventListener('click', function() { this.style.background='black'; scr+=10; cnt+=10; this.innerHTML= 'SCORE = ' +String(scr); }); var b=document.getElementById('Maincont'); // FIRST HIT ME BOX IS READY NOW.... b.appendChild(Name); // Array numOfbox loaded with all the Box id's. numOfbox.push(Name.id); console.log('PUSHING DIV:-'+ Name.id + " IN ARRAY :=" +numOfbox); // creatediv is called when score is scr%30==0. if (numOfbox.length > 1) { return Name.id; } } function Initialize() { if (main.childNodes.length < 5) { if ((cnt > 0) && (cnt %30 ==0)) { var id='targetCont'+divcnt; divcnt+=1; boxId=createDiv(id,'130px','50px','black','0px','0px'); console.log('Inside Initialize:-'+id+' cnt '+ cnt); cnt=0; } startGame(); } } function startGame() { var d=new Date(); var t=d.getMinutes()+':'+d.getSeconds(); fcnt+=1; console.log('TIME IS:-'+ t + " cnt:-" +fcnt+' INSIDE STARTGAME:-'+numOfbox+':'+numOfbox.length+ ' CNT'+cnt); for (var i=0 ; i < numOfbox.length ; i++) { if ((cnt > 0) && (cnt %30 ==0)) { Initialize(); } else { console.log('STARTING GAME FOR DIV:='+numOfbox[i]); var box=document.getElementById(numOfbox[i]); console.log(box); box.disabled=false; var max=500; var min=10; var topRand=(Math.floor(Math.random() * (max-min+1) + min)); var max=1200; var min=10; var leftRand=(Math.floor(Math.random() * (max-min+1) + min)); box.style.background='black'; box.style.top=topRand+'px'; box.style.left=leftRand+'px'; console.log('CNT:='+cnt); timeout=setTimeout(startGame,10000,numOfbox); } } } function stopGame() { clearTimeout(timeout); console.log('IN STOPGAME:-'+timeout+' length '+timeout.length); for (var i=0 ; i < numOfbox.length ; i++) { console.log(timeout[i]); clearTimeout(timeout[i]); var box=document.getElementById(numOfbox[i]); box.style.background='red'; box.style.top='10px'; box.style.left='10px'; } timeout=[]; } 。因此,如果你有setTimeoutnumOfbox.length === 15将在你设置它的时候在setTimeout ms周围被调用15次。这可能是你看到10,000比你想象的更多的电话吗?
  2. 我看到变量startGame,但由于它没有在numOfbox函数中声明,我将不得不假设它在父范围内。所以,在你做的那一行 startGame

意识到由于timeout[i] = setTimeout(startGame, 10000, numOfbox); 处于更高级别的范围而且numOfbox不接受任何参数,所以startGame参数(numOfbox中的第3个参数)实际上不会去任何地方:实际使用的setTimeout变量来自父范围。这可能没问题,但你应该考虑一下这里发生了什么。

© www.soinside.com 2019 - 2024. All rights reserved.