2011-08-18 118 views
1

我有一段代码会颠倒我窗体上的所有复选框。我有多个元素(不仅仅是复选框,而且还有<input type='text'>)。我需要优化它的原因是因为它需要大约两到三秒来选择所有复选框(现在275)。有没有什么办法可以优化这段代码?

这里是我的代码:

function FormInverse() { 
    var iCheckbox = 1; // Because there are multiple input elements, we need to distinquish the input element ID and the row id 
    var FormLength = document.FormFacturen.elements.length; 
    for (i=0; i < FormLength; i++) { 
     var FormElementType = document.FormFacturen.elements[i].type; 
     if (FormElementType == "checkbox") { 
      var Elements = document.getElementsByClassName('row' + iCheckbox); // Alle elementen in de array zetten 
      var iNumElements = Elements.length; 
      for (iElement=0; iElement < iNumElements; iElement++) { 
       if (document.FormFacturen[i].checked == true) { 
        Elements[iElement].className = "invoice-tr-standard row" + iCheckbox; 
       } else { 
        Elements[iElement].className = "invoice-tr-clicked row" + iCheckbox; 
       } 
      } 
      iCheckbox++; 
      document.FormFacturen[i].checked = !document.FormFacturen[i].checked; 
     } 
    } 
} 

这里是document.getElementsByClassName功能:

document.getElementsByClassName = function(cl) { 
    var retnode = []; 
    var myclass = new RegExp('\\b'+cl+'\\b'); 
    var elem = document.getElementsByTagName('*'); 
    for (var i = 0; i < elem.length; i++) { 
     var classes = elem[i].className; 
     if (myclass.test(classes)) retnode.push(elem[i]); 
    } 
    return retnode; 
}; 
+2

为什么你不会利用像jQuery的东西?这种类型的脚本在jQuery中非常简单。 –

+0

@Josh,因为我从来没有真正与jQuery合作过,所以我没有经历过它。如果最终结果是它会更快,那就没问题。 – Devator

+1

我一定会检查浏览器是否已经实现了'document.getElementsByClassName()'或者Selectors API,如果它们存在,就使用它们,如果它们不存在,则返回到你的函数。它们可能会快得多。 –

回答

3

我会建议使用jQuery。

试试这个:

增加提及jQuery的:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript" language="JavaScript"></script> 

使用此代码:

$(':checkbox').each(function() { 
    $(this).attr('checked', !$(this).attr('checked')); 
}); 

编辑: 或者用它来改变类和:

$(':checkbox').each(function() { 
    var checked = $(this).attr('checked'); 
    if (checked) { 
     $(this).attr('checked', false); 
     $(this).addClass('invoice-tr-clicked'); 
     $(this).removeClass('invoice-tr-standard');   
    } 
    else { 
     $(this).attr('checked', true); 
     $(this).addClass('invoice-tr-standard'); 
     $(this).removeClass('invoice-tr-clicked'); 
    } 
}); 

最终版本:

$('#FormFacturen :checkbox').each(function() { 
    var checked = $(this).attr('checked'); 
    if (checked) { 
     $(this).attr('checked', false); 
     $(this).parents('tr').addClass('invoice-tr-clicked'); 
     $(this).parents('tr').removeClass('invoice-tr-standard');   
    } 
    else { 
     $(this).attr('checked', true); 
     $(this).parents('tr').addClass('invoice-tr-standard'); 
     $(this).parents('tr').removeClass('invoice-tr-clicked'); 
    } 
}); 
+0

然后我将如何更改课程? attr('class','invoice-name')这是我的第一篇文章:'for(iElement = 0; iElement Devator

+0

您可以添加: $(':checkbox:checked' tr标准行'); $(':checkbox:not(:checked)')。attr('class','invoice-tr-clicked row'); – Tejo

+0

谢谢,但该行通常通过Javascript('“invoice-tr-standard row”+ iCheckbox;')传递,我仍然需要保留随ID一起发送的id(iCheckbox)(每行不同)。 – Devator

1

你应该看看像jQuery库。它会很好地处理这种事情。

虽然有很多小事情可以改善您的代码。我注意到的第一件事是你的getElementsByClassName函数在你每次调用它时遍历页面上的所有元素。你可以改变这一行:

var elem = document.getElementsByTagName('*'); 

只得到输入元素:

var elem = document.getElementsByTagName('input'); 
+0

谢谢,它已经减少了50%(但它仍然是一个胖的秒 - 所以它仍然使用太慢)。 – Devator

2

getElementsByClassName每次调用是昂贵的,它被称为在你的每个通行证循环。

除了@杰夫的建议,你可以调用document.getElementsByTagName('input');只是一次,而不是每次都getElementsByClassName被调用,并缓存结果为你的循环中使用。

这需要对您的getElementsByClassName函数进行小小的修改,从而它接受要搜索的元素数组。

document.getElementsByClassName = function(cl, eles) { 
    var retnode = []; 
    var myclass = new RegExp('\\b'+cl+'\\b'); 
    var len = eles.length; 
    for (var i = 0; i < len; i++) { 
     var classes = eles[i].className; 
     if (myclass.test(classes)) retnode.push(eles[i]); 
    } 
    return retnode; 
}; 


function FormInverse() { 
    // cache all inputs 
    var inputs = document.getElementsByTagName("input"); 
    ... 
    // later 
    var Elements = document.getElementsByClassName('row' + iCheckbox, inputs); 
+0

我试过了,但没有奏效。它仍然很慢。也许是因为我正在改变tr类? – Devator

0

我非常肯定的瓶颈这里是getElementsByClassName功能,浏览器需要每次都找到自己的元素重新扫描整个HTML。我建议你给你的元素一个唯一的ID id="row1",id="row2",...而不是一个独特的类名称,并使用getElementById这是更快。

var Elements = document.getElementsById('row' + iCheckbox); 
+0

我无法使用此方法,因为我的ID不是唯一的。请参阅[此链接](http://stackoverflow.com/questions/7092421/changing-class-of-same-id)了解更多关于为什么我无法使用它的信息。 – Devator

+0

@Devator我发布了一个答案[你的其他问题](http://stackoverflow.com/questions/7092421/changing-class-of-same-id/7107619#7107619),这也将解决你的问题。 – nobody

相关问题