2014-01-08 87 views
1

我在使用javascript中的appendchild行的chrome中遇到了速度问题。这似乎在Firefox和Chrome中运行良好,但不是Chrome非常慢。我只是试图在点击按钮上添加一个元素。该页面已经有超过10,000个元素,但我不确定这是否是问题的一部分。Chrome中的appendChild性能问题

只为了解我看过的东西。我查阅了文档片段,并试图实现它,但得到了相同的结果。从我所收集的内容来看,documentfragment通常会在您将很多元素添加到dom时提高性能,而不仅仅是一个。 (如果我在这个假设上错了,请随时纠正我)。我也在Chrome中运行时间线,发现“布局”需要11.91秒才能加载,并且似乎陷入了appendchild行。我在下面评论了这条线。

正如我前面提到的,我已经尝试过没有改进的documentfragment,所以这是我的原始代码。

function addYr() { 
     divArray = document.getElementById('acct_sect').getElementsByTagName("div"); 
     divRow = document.createElement("div"); 
     divRow.id = "acct_row_" + (divArray.length); 

     var yr = document.createElement("input"); 
     yr.type= "text"; 
     yr.id= "yr_" + divArray.length; 
     yr.name= "yr_" + divArray.length; 
     yr.setAttribute("onkeydown", "TabNext(this,'down',2); return justNums(event);"); 
     yr.setAttribute("onkeyup", "TabNext(this,'up',2,this.form.fnd_)"); 
     yr.maxLength = 2; 
     yr.className = "c1"; 
     yr.setAttribute("onchange", "buildAccountMultiRow(this)"); 
     yr.value = ""; 

     divRow.appendChild(yr); 


    //line that is taking a while 
    document.getElementById('acct_sect').appendChild(divRow); 
} 
+1

它可能会更快,如果你没有设置事件处理程序的字符串属性(必须evalled),但作为标准功能(即'yr.onkeydown =函数(){.. .'),对所有元素使用相同的函数会更好。 –

+0

@dystoy,感谢您的评论。我会试试这个。这可能只是我笨拙的阅读理解,但当你说“对所有元素使用相同的功能”时,你是什么意思。 – chuckw87

+0

我的意思是你的字符串是一样的。因此,只需在循环外定义一个函数'function myFunction(){TabNext(this,'down',2);返回justNums(event)}'并且在追加时执行'yr.onkeydown = myFunction'。 –

回答

1

的大量元素是最容易惹的祸,但这里的一些尝试:

  • getElementsByTagName返回一个实时列表,必须每次改变时更新。相反,试试这个:

    divArray = document.getElementById('acct_sect').children; 
    
  • 如果你不使用任何东西的id属性,删除。

  • 如果可以重新在服务器上的一些代码,尝试:

    yr.name = "yr[]"; 
    

    然后在服务器上,你会得到(例如在PHP)$_POST['yr']作为包含值的数组。

  • 如果你可以同时做上述两项,那么你会发现你甚至不需要divArray,并且可以完全摆脱那个,这应该节省很多时间。
  • 尝试改变处理事件的方式。不要为每个元素分配三个事件处理程序,而是将一个事件处理程序分配给容器。

    var ac = document.getElementById('acct_sect'); 
    ac.onkeydown = function(e) { 
        e = e || window.event; 
        var t = e.srcElement || e.target; 
        if(t.nodeName == "INPUT") { 
         tabNext(t,'down',2); 
         return justNums(e); 
        } 
    }; 
    ac.onkeyup = function(e) { 
        e = e || window.event; 
        var t = e.srcElement || e.target; 
        if(t.nodeName == "INPUT") { 
         tabNext(t,'up',2,t.form.fnd_); 
        } 
    }; 
    ac.onchange = function(e) { 
        e = e || window.event; 
        var t = e.srcElement || e.target; 
        if(t.nodeName == "INPUT") { 
         buildAccountMultiRow(t); 
        } 
    };