2011-07-15 46 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"); 

然后,可以做任何你需要做的只是这两个元素。我敢打赌,这种方法也会摆脱你的无限循环问题。