Борясь с производительностью, как я могу изменить это, чтобы использовать для циклов? - PullRequest
0 голосов
/ 16 марта 2012

У меня есть функция, которая проверяет каждую ячейку в каждой строке таблицы на класс edit-error.Если это найдено в какой-либо ячейке определенной строки (значение ячейки не прошло проверку), я удаляю класс edit-submit из всей строки и снимаю флажок, который находится в первой td этой строки.

Когда большое количество строк (более 1000), я борюсь с производительностью, поэтому я подумал, что могу попробовать циклы, но я не эксперт в JavaScript, поэтому ищу помощь в этом.

Исходный код выглядит следующим образом:

var checkErrors = function () {
    $('#results tr:not(:first)').each(function () {
        $('td:first input:checkbox', $(this)).attr('checked', 'checked');
        $(this).addClass('edit-submit');

        $(this).find('td').each(function () {
            if ($(this).hasClass('edit-error')) {
                $('td:first input:checkbox', $(this).parent('tr')).removeAttr('checked');
                $(this).parent().removeClass('edit-submit');
            }
        });
    });
}

Таблица имеет идентификатор #results.Сначала я проверяю все флажки и добавляю класс edit-submit в каждую строку, а затем перебираю все ячейки, проверяющие на наличие ошибок.

Мне нужна помощь в улучшении производительности этой функции.1015 *

РЕДАКТИРОВАТЬ

Было бы целесообразно добавить таблицу HTML.Извинения за это вот это:

<table id="results">
    <tbody>
        <tr>
            <th>&nbsp;</th>
            <th>Policy Number</th>
            <th>Quota Code</th>
            <th>Contract Date</th>
        </tr>
        <tr>
            <td><input type="checkbox"></td>
            <td class="edit-error">ABC123%</td>
            <td>123</td>
            <td class="edit-error">99/99/9999</td>
        </tr>
        <tr class="edit-submit">
            <td><input type="checkbox" checked="checked"></td>
            <td>ABC123</td>
            <td>123</td>
            <td>16/03/2012</td>
        </tr>
    </tbody>
</table>

Это будет показано на странице:

--------------------------------------------------
|   | Policy Number | Quota Code | Contract Date |
--------------------------------------------------
|   | ABC123%       | 123        | 99/99/9999    |
--------------------------------------------------
| X | ABC123        | 123        | 16/03/2012    |
--------------------------------------------------

Ответы [ 4 ]

1 голос
/ 16 марта 2012

Есть несколько способов ускорить ваш код, не переходя на простой цикл JS for. Чтобы назвать только несколько:

  • У вас уже есть ссылка на текущую строку во внешнем цикле .each(), поэтому используйте ее вместо вызова $(this).parent() во внутреннем цикле.
  • Если вы хотите обработать только те элементы td, которые имеют определенный класс, вы можете включить этот класс в ваш селектор, а не вызывать .hasClass().
  • Старайтесь не вызывать один и тот же селектор более одного раза, сохраняя ссылку на возвращенный объект jQuery и / или используя цепочку.
  • При предоставлении контекста в качестве второго параметра для $() вы можете передать элемент DOM или this напрямую, не нужно заключать его в другой вызов $().
  • Если вы знаете, что флажок всегда будет, вы можете снять его непосредственно, чтобы сохранить вызов функции.

Итак:

var checkErrors = function () {
    $('#results tr:not(:first)').each(function () {
        var $tr = $(this),
            cb = $('td:first input:checkbox', this)[0];

        cb.checked = true;

        $tr.addClass('edit-submit')
           .find('td.edit-error').each(function () {
                cb.checked = false;
                $tr.removeClass('edit-submit');
           });
    });
};

Тем не менее, внутренний цикл в tds вообще не нужен, так как вам просто нужно проверить, есть ли в строке tds с классом ошибок - вам не нужно фактически проходить через них все. Кроме того, для правильной оценки есть один способ использовать цикл for вместо .each() - обратите внимание, что вы можете избежать сложного не-первого селектора, если просто выделите все строки, а затем начнете цикл со второго и далее:

var checkErrors = function () {
    var $rows = $('#results tr'),
        i;
    for (i = 1; i < $rows.length; i++) {
        var $tr = $rows.eq(i),
            cb = $tr.find('td:first input:checkbox')[0];

        if ($tr.find('td.edit-error').length === 0) {
           cb.checked = true;
           $tr.addClass('edit-submit');
        } else {
           cb.checked = false;
           $tr.removeClass('edit-submit');
        };
    }
};
0 голосов
/ 16 марта 2012

Попробуйте это:

   $.each($('#results .edit-error').parent(),function(){
            $(this).removeClass('edit-submit').find('td:first-child input:checkbox').removeAttr('checked');
});
0 голосов
/ 16 марта 2012

Используйте переменную для $ (this).

Ваши селекторы также можно улучшить: вместо $('#this', '#that') используйте $('#that').find('#this')

Вот улучшенная версия с этими оптимизациями.

var checkErrorsOptimized = function () {

    $('#results tr:not(:first)').each(function () {
        var $this = $(this);       

        $this.find('td:first input:checkbox').attr('checked', 'checked');
        $this.addClass('edit-submit');

        $this.find('td').each(function () {
            var $that = $(this);
            if ($that.hasClass('edit-error')) {
                $that.parent('tr').find('td:first input:checkbox').removeAttr('checked');
                $that.parent().removeClass('edit-submit');
            }
        });
    });
}

Вы можете увидеть это на этом jsFiddle (используя профилирование Firebug): http://jsfiddle.net/5kBsU/3/

0 голосов
/ 16 марта 2012

Попробуйте установить переменную для $ (это).Также вам нужно использовать find ('td')?Будет ли $ ('td', this) делать то же самое, но более эффективно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...