2011-08-18 211 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

相關問題