2016-03-08 154 views
0

我是編碼新手,我想用HTML,CSS和Javascript構建文本冒險遊戲。我想在每個文本之間顯示一定數量的文本。我嘗試了不同的方法,以避免由於setTimeout造成的無限循環,但我沒有弄清楚如何將其應用於我的代碼。'while'內的setTimeout導致瀏覽器崩潰。我怎樣才能避免它?

這裏是我的代碼,這導致崩潰:

var iCounterText = 0; 

var verzog = function() { 
    document.getElementById('toggleText').insertAdjacentHTML('beforeBegin', '<br>--------------<br>'); 
    document.getElementById('toggleText').insertAdjacentHTML('beforeBegin', part1[iCounterText]); 
    iCounterText = iCounterText + 1; 
    playaudio(); 
} 

function forwardingLinks() { 
    while (iCounterText < part1.length - 1) { 
    setTimeout(verzog, 500); // Here is the problem // 
    } 
    document.getElementById('buttonLinks').innerHTML = part1[part1.length - 1]; 
} 

下面的代碼工作正常,但再有就是文本之間沒有超時:

function forwardingLinks() { 
    while (iCounterText < part1.length - 1) { 
    verzog(); 
    } 
    document.getElementById('buttonLinks').innerHTML = part1[part1.length - 1]; 
} 

編輯: 這是我用「setInterval」創建的新代碼。問題:值加1,但函數不使用part2數組。相反,它再次使用part1 Array,但partvalue已經包含part2數組。

var part1 = [       //Texte und Antworten 
'Hallo?', 
'Test?', 
'What', 
'hello', 
'--------------', 

'Was?' 
]; 

var part2 = [       //Texte und Antworten 
'part2 goes on....', 
'bla bla', 
'blablabla' 

]; 

var iCounterText = 0;       
var value = 1; 
var partvalue = eval("part" + value); 

function forwardingLinks() { 
var verzog = setInterval(function(){ 
if(iCounterText < partvalue.length-2){ 
++iCounterText; 
toggleText.insertAdjacentHTML('beforeBegin', '<br>--------------<br>'); 
toggleText.insertAdjacentHTML('beforeBegin', partvalue[iCounterText]); 
playaudio(); 
}else{ 
    buttonLinks.innerHTML = partvalue[partvalue.length-1]; 
    ++value; 
    iCounterText=0; 
    clearInterval(verzog); 

} 
},500); 
} 
+1

您不會在'while循環中更改'iCounterText',那麼循環如何停止?在超時函數運行之前,您不要更改它,但直到退出循環纔會發生這種情況。 – Barmar

+0

使用'setInterval'每500毫秒運行一次函數。當計數器達到限制時,它應該調用'clearInterval'來自行停止。 – Barmar

+0

您也可以嘗試在添加的元素上添加轉換時間,而不是暫停 – ryan

回答

0

您誤解了while循環的流程。 JavaScript在單線程環境中運行。這意味着您的撥打verzog函數將不會運行,直到forwardingLinks函數完成,但您的forwardingLinks函數將永遠不會完成,因爲您有一個while循環取決於永不增加的計數器,因爲verzog還沒有還沒有運行。

更改您的while循環,使iCounterText變量被從內環路遞增,所以循環可以結束,然後,在事件隊列都疊起來verzog呼叫可以開始運行。

此外,由於您使用的是數字計數器,一個普通for循環會因爲需要循環的步長值(++iCounterText)是比while循環更好:

for(var iCounterText = 0; iCounterText < part1.length; ++iCounterText) { 
    setTimeout(verzog, 500); 
} 

從您的主要問題的擱置,如同您在verzog函數中所做的那樣,反覆掃描DOM的相同元素的效率非常低下。相反,只需獲取一次DOM參考並將其存儲在一個可以重複使用的變量中:

// Declare a variable in a scope that is accessible throughout your code 
var toggleText = null, buttonLinks = null; 

// Set up a callback that runs after the DOM is ready 
window.addEventListener("DOMContentLoaded", function(){ 

     // Scan the DOM for the element(s) you'll be needing 
     toggleText = document.getElementById('toggleText'); 
     buttonLinks = document.getElementById('buttonLinks'); 

}); 

function verzog() { 
    // Now, you can just refer to the DOM element you've already found: 
    toggleText .insertAdjacentHTML('beforeBegin', '<br>--------------<br>'); 
    toggleText .insertAdjacentHTML('beforeBegin', part1[iCounterText]); 
    playaudio(); 
} 

function forwardingLinks() { 
    for(var iCounterText = 0; iCounterText < part1.length; ++iCounterText) { 
     setTimeout(verzog, 500); 
    } 

    // Now, you can just refer to the DOM element you've already found: 
    buttonLinks.innerHTML = part1[part1.length - 1]; 
} 
+0

謝謝,我今天會試一試。是否有可能避免「.insertAdjacentHTML」重新排序?我想沒有辦法將一個變量和html代碼放入一個函數中? – Christian

+0

我編輯了我的代碼,但現在我得到數組「part1」的第一個文本的6倍,並且這些文本之間沒有超時。該函數在iCounterText> part1.length時停止,但verzog()函數不適用於新的iCounterText值。它總是使用part1 [0]。 – Christian

+0

你可以發佈所有相關的代碼,以便我們可以確切地看到你在做什麼? –

相關問題