有没有办法优化这段代码?

时间:2011-08-18 11:25:16

标签: javascript

我有一段代码会反转我表单上的所有复选框。我有多个元素(不仅仅是复选框,还有<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;
};

4 个答案:

答案 0 :(得分: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');
    }
});

答案 1 :(得分:2)

getElementsByClassName的每次调用都很昂贵,并且在for循环的每次传递中都会调用它。

除了@Geoff的建议之外,你可以只用一次调用document.getElementsByTagName('input');,而不是每次调用getElementsByClassName,并缓存结果以便在循环中使用。< / p>

这需要对您的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); 

答案 2 :(得分:1)

您应该查看像JQuery这样的库。它会很好地处理这类事情。

尽管如此,您仍可以通过很多小方法来改进代码。我注意到的第一件事是你的getElementsByClassName函数每次调用时都会遍历页面上的所有元素。你可以改变这一行:

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

只获取输入元素:

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

答案 3 :(得分:0)

我非常确定这里的瓶颈是getElementsByClassName函数,浏览器每次都需要重新扫描整个html才能找到你的元素。我建议您为元素添加唯一ID id="row1"id="row2",...而不是唯一的类名,并使用更快的getElementById

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