2016-03-06 171 views
0

所以我有一個名爲lines的列表,它的每一行設置都是分開的。然後那些被髮送到另一個名爲rdline()的函數讀取它。我已經設置了一個警報,以查看通過它的內容,並且只有在陣列中有多個條目時纔會發出警報。只能執行一次的函數

var ms = false; 
 
var ss; 
 
var c; 
 
var lc; 
 
var lines = []; 
 
var currset; 
 
var win; 
 
var sendline = 0; 
 
var op = function() { 
 
    document.getElementById('rd').innerHTML = "Reading..."; 
 
    ss = document.getElementById('t').innerHTML; 
 
    c = document.getElementById('t').innerHTML; 
 
    document.getElementById('t').innerHTML = ""; 
 
    lc = 0; 
 
    lines = []; 
 
    currset = []; 
 
    setLines(c); 
 
} 
 
var setLines = function(cont) { 
 
    for (i = 0; i < cont.length; i++) { 
 
    if (cont[i] == ";") { 
 
     lines[lc] = currset.join("").replace("<br>", "") + " "; 
 
     lc++; 
 
     currset = []; 
 

 
    } else { 
 
     currset[i] = cont[i]; 
 
    } 
 
    } 
 
    for (i = 0; i < lines.length; i++) { 
 
    rdline(lines[i]) 
 
    } 
 
    
 
} 
 
var rdline = function(parg) { 
 
    //EXECUTING ONCE! 
 
    alert(parg) 
 
    //the rest should be fine 
 
    var pl = []; 
 
    var toplace = []; 
 
    var pcount = 0; 
 
    for (i = 0; i < parg.length; i++) { 
 
    if (parg[i] == " ") { 
 
     pl[pcount] = toplace.join(""); 
 
     pcount++; 
 
     toplace = []; 
 
    } else { 
 
     toplace[i] = parg[i]; 
 
    } 
 
    } 
 
    //functions 
 
    if (pl[0] == "$setupmemes") { 
 
    ms = true; 
 
    win = window.open("", "", "height=800", "width=800") 
 
    } 
 
    if (ms == true) { 
 
    if (pl[0] == "expand") { 
 
     win.document.write('dongs') 
 
    } 
 
    } 
 
    document.getElementById('t').innerHTML = ss; 
 
}
code { 
 
    width: 100%; 
 
    height: 100vh; 
 
    border: none; 
 
    background: black; 
 
    color: white; 
 
    font-size: 150%; 
 
    font-family: sans-serif; 
 
    display: inline-block; 
 
}
<button onClick='op()'>Run</button> 
 
<span id='rd'></span> 
 
<br /> 
 
<br /> 
 
<code contenteditable="true" id='t'></code>
運行段和類型:

$ setupmemes; expand;

+0

非常抱歉,但我的代碼中的警報是在_var rdline = function(parg)_ –

+1

之後不要遺憾,請將您的解決方案作爲答案並標記爲正確。 –

+0

這不是答案,當我寫這個時,警報函數沒有複製。我指出了代碼中警報的位置。 –

回答

0

的問題是,在你的setlines功能,您有一個循環,它使用i作爲計數器,但你沒有使用var初始化它,這使得它的全局變量:

function setLines(cont) { 
    // RIGHT HERE, YOU ARE NOT DECLARING i WITH var 
    for (i = 0; i < cont.length; i++) { 
    if (cont[i] == ";") { 
     lines[lc] = currset.join("").replace("<br>", "") + " "; 
     lc++; 
     currset = []; 

    } else { 
     currset[i] = cont[i]; 
    } 
    } 

    // RIGHT HERE, YOU ARE NOT DECLARING i EITHER, SO THE PREVIOUS 
    // i VALUE IS RESET TO ZERO (NOT A PROBLEM YET, BUT IT WILL BE) 
    for (i = 0; i < lines.length; i++) { 
    rdline(lines[i]) 
    } 
} 

而所以,i成爲一個全局變量。然後,在你rdline功能,您有另一個循環,也使用i,但同樣沒有聲明它:

function rdline(parg) { 
    //EXECUTING ONCE! 
    alert(parg) 
    //the rest should be fine 
    var pl = []; 
    var toplace = []; 
    var pcount = 0; 

    // USE OF GLOBAL i again! i is again reset to zero 
    // This loop allows i to go to a higher value than 
    // the first loop that sent you to this one! 
    for (i = 0; i < parg.length; i++) { 
    if (parg[i] == " ") { 
     pl[pcount] = toplace.join(""); 
     pcount++; 
     toplace = []; 
    } else { 
     toplace[i] = parg[i]; 
    } 
    } 

正是這種循環使用相同的全局i變量作爲第一個允許i到增量到36(在第一時間rdline被調用。當rdline完成並返回到所述第一環路,i是大於lines.length因此第一循環終止。

解決方法是始終聲明您的循環變量(優選地在循環)如:

 // Notice the var? 
     for(var i = 0; ... 

,並使用不同的循環變量時,都需要在同一範圍內多次循環。在功能rdline的循環變量更改爲一個不同的名稱和var它在該循環,如:

 // When multiple loops exist in the same scope, 
     // always use a different counter for each loop! 
     for(var x = 0; ... 

請記住,在JavaScript中,你沒有默認塊級範圍(您可以創建塊級別範圍順便說一下,新的let關鍵字)。如果兩個(或多個)循環使用同一個作用域中相同的循環變量,則一個函數中設置的尚未聲明的變量(編號爲var)將變爲全局變量並且沒有塊作用域(默認情況下),一個循環將導致反對在該範圍內的所有循環進行更改。