2011-07-15 103 views
3

嗨我有這個JavaScript,當用戶點擊一個按鈕時添加一個文本框。該文本框然後被添加到DOM網頁。這個javascript崩潰我的瀏覽器

但是它現在似乎並沒有停下來,並且陷入了一個無限循環。

循環使用

的getElementsByTagName

以及有多少的限制,但它是對前面工作的罰款。

//add rows function 
window.onload=function() 
{ 

s=5; //for staff 
n=20; //for events 

//sets at default incase no js rows created 
var staffbox = document.getElementById('staffcounter'); 
        staffbox.value = s; 

var eventsbox = document.getElementById('eventscounter'); 
        eventsbox.value = n; 



inp=document.getElementsByTagName('input'); 
for(c=0;c<inp.length;c++) // <---- I think this bit is causing the crash! 
    { 
     if(inp[c].name=='addstaff') 
     { 
      inp[c].onclick=function() 
      { 
       var sel = document.createElement('select'); 
       sel.name = 'staff' + s; 



       option1 = document.createElement('option'); 
       option1.name = 'Please select'; 
       option1.value = ''; 

       option1.innerHTML = option1.value; 

       option2 = document.createElement('option'); 
       option2.name = 'Nurse'; 
       option2.value = 'Nurse'; 
       option2.innerHTML = option2.value; 

       sel.appendChild(option1); 
         sel.appendChild(option2); 

       document.getElementById('staffarea').appendChild(sel); 



       x=document.createElement('input'); 
       x.setAttribute('rows',1); 
       x.setAttribute('cols',20); 
       x.name='staffquantity'+s; 
       document.getElementById('staffarea').appendChild(x) 

       document.getElementById ('staffarea').innerHTML += '<br>'; 

       // This bit updates a counter that will be $_POST 
       var staffbox = document.getElementById('staffcounter'); 
        staffbox.value = s; 


       s++; 
      } 


     } 

     else if(inp[c].name=='addevent') 
     { 

       timemaker(); // calls another function which creates a specific text box 

       x=document.createElement('input'); 
       x.setAttribute('rows',1); 
       x.setAttribute('cols',20); 
       x.name='event'+n; 
       document.getElementById('eventarea').appendChild(x); 


       x=document.createElement('input'); 
       x.setAttribute('rows',1); 
       x.setAttribute('cols',20); 
       x.name='supplies'+n; 
       document.getElementById('eventarea').appendChild(x); 

       x=document.createElement('input'); 
       x.setAttribute('rows',1); 
       x.setAttribute('cols',20); 
       x.name='manufacturer'+n; 
       document.getElementById('eventarea').appendChild(x); 

       x=document.createElement('input'); 
       x.setAttribute('rows',1); 
       x.setAttribute('cols',20); 
       x.name='quantity'+n; 
       document.getElementById('eventarea').appendChild(x); 

      var sel = document.createElement('select'); 
      sel.name = 'success' + n; 


        y = document.createElement('option'); 
        y.name = 'Yes'; 
        y.value = 'Yes'; 
        y.innerHTML = y.value; 

        x = document.createElement('option'); 
        x.name = 'No'; 
        x.value = 'No'; 
        x.innerHTML = x.value; 


         sel.appendChild(y); 
         sel.appendChild(x); 


        document.getElementById('eventarea').appendChild(sel); 


       x=document.createElement('input'); 
       x.setAttribute('rows',1); 
       x.setAttribute('cols',20); 
       x.name='comment'+n; 
       document.getElementById('eventarea').appendChild(x); 

       document.getElementById ('eventarea').innerHTML += '<br>'; 

       // This bit updates a counter that will be $_POST 
       var eventsbox = document.getElementById('eventscounter'); 
        eventsbox.value = n; 

      n++; 

      } 


     } 
    return; 
} 

感謝

+0

是否有任何理由,你爲什麼不檢索通過ID輸入?在這種情況下你不需要循環。 – FishBasketGordo

+0

我不知道,我只是修改了一個只添加了一個文本框的示例代碼, – giedrere

回答

4

HTMLCollection是實時查詢的。

含義:在DOM

節點列表和的NamedNodeMap對象是活的;也就是說,對底層文檔結構的更改會反映在所有相關的NodeList和NamedNodeMap對象中。例如,如果DOM用戶獲取包含元素的子元素的NodeList對象,然後隨後向該元素添加更多子元素(或刪除子元素或修改它們),那麼這些更改會自動反映到NodeList中,而不會對用戶的一部分。同樣,對樹中節點的更改反映在NodeList和NamedNodeMap對象中對該節點的所有引用中。

這就是爲什麼你得到一個無限循環。

inp=document.getElementsByTagName('input'); 

在循環中,我看到新的<input>的創建。

x=document.createElement('input'); 

因此,解決辦法應該是更改爲inp=document.querySelectorAll("input") 或者有長度的靜態變量

像這樣:

var = inp=document.getElementsByTagName('input'), 
     inputsLength = inp.length; 

for(c=0;c<inputsLength;c++){ 
... loop .... 

} 
+1

謝謝你一個非常有見地的答案。 – giedrere

2

當您添加一個輸入元素的INP改變您的文檔計數。

inp=document.getElementsByTagName('input'); 

所以這是一個無限循環,當你依靠INP的數量,並添加一個輸入每次迭代。

將長度賦給變量並將其用於循環。

inpCount = document.getElementsByTagName('input').length; 
+0

'inp'在循環中被修改了哪裏?我一定錯過了。 – FishBasketGordo

+0

inp是文檔中輸入元素的數組。如果您向文檔添加一個輸入,則會將inp的計數增加1。謝謝 –

0

如果你只需要做的事情與<input name="addEvent" /><input name="addStaff" />,那麼你可以通過給這些元素獨特的id屬性正是如此檢索它們簡化你的腳本一點:

var addEventInp = document.getElementById("addEventID"); 
var addStaffInp = document.getElementById("addStaffID"); 

然後,可以做任何你需要做的只是這兩個元素。我敢打賭,這種方法也會擺脫你的無限循環問題。