Медленный селектор jQuery при выборе класса

0

У меня есть следующая таблица.

<table>
    <tr>
        <td>Name</td>
        <td>01</td>
        <td>02</td>
        <td>03</td>
        <td>04</td>
        <td>05</td>
    </tr>
    <tr>
        <td class="tdName">Smith</td>
        <td class="tdTime" id="td_smith_01">1</td>
        <td class="tdTime" id="td_smith_02">%nbsp;</td>
        <td class="tdTime" id="td_smith_03">1</td>
        <td class="tdTime" id="td_smith_04">%nbsp;</td>
        <td class="tdTime" id="td_smith_05">2</td>
    </tr>
    <tr>
        <td class="tdName">Miller</td>
        <td class="tdTime" id="td_miller_01">%nbsp;</td>
        <td class="tdTime" id="td_miller_02">2</td>
        <td class="tdTime" id="td_miller_03">%nbsp;</td>
        <td class="tdTime" id="td_miller_04">2</td>
        <td class="tdTime" id="td_miller_05">1</td>
    </tr>
    <tr>
        <td class="tdName">Underwood</td>
        <td class="tdTime" id="td_underwood_01">%nbsp;</td>
        <td class="tdTime" id="td_underwood_02">%nbsp;</td>
        <td class="tdTime" id="td_underwood_03">1</td>
        <td class="tdTime" id="td_underwood_04">1</td>
        <td class="tdTime" id="td_underwood_05">%nbsp;</td>
    </tr>
    <tr>
        <td class="tdName">Stinson</td>
        <td class="tdTime" id="td_stinson_01">2</td>
        <td class="tdTime" id="td_stinson_02">2</td>
        <td class="tdTime" id="td_stinson_03">%nbsp;</td>
        <td class="tdTime" id="td_stinson_04">%nbsp;</td>
        <td class="tdTime" id="td_stinson_05">1</td>
    </tr>
</table>

На самом деле это намного больше и сложнее. Теперь я хочу добавить слушателя кликов каждый раз в каждую ячейку таблицы, поэтому каждая ячейка класса "tdTime", поэтому я добавил:

    var tdTimes = $(".tdTime");
    tdTimes.onclick( 
        function() {
            switch($(this).html()) {
                ...a switch to change the time in the td.
            } 
        }
    );

Как я уже упоминал, реальная таблица намного больше (длина tdTimes> 15 000), поэтому IE требует около ~ 8 000 мс, чтобы добавить слушателя в каждую ячейку, для Chrome все еще требуется около 3000 мс. На многих сайтах было предложено использовать ids в качестве селектора, чтобы сделать это быстрее, но, как вы видите, у меня уже есть идентификаторы, и почти невозможно использовать эти идентификаторы в этом случае, потому что таблица - снова - намного больше сложный, чем простой пример.

Что бы вы посоветовали ускорить этот процесс? В другом посте я читал о подсказке, чтобы дать селекторам контекст, должен ли я дать строкам таблицы последовательный идентификатор ("trTime1", "trTime2",...), а затем запомнить количество этих строк, а затем сделать для цикла добавить слушателя? Что-то вроде:

for(var i = 1; i <= trTimelength; i++) {
    var tdTimes = $('.tdTime', '#trTime' + i)
    tdTimes.click(
        ...
    )
};

Спасибо за помощь ребята!

EDIT: Как правильно сказал А. Вольф, 15 000 ячеек слишком много для отображения - я бы хотел добавить, что большинство этих ячеек скрыты в начале. Поэтому после загрузки страницы у меня нет проблем с производительностью. (Но, к сожалению, клеткам нужен слушатель)

  • 2
    Вы должны разбить свой стол на страницы. Показывать более 15000 ячеек одновременно - это слишком много. Тем не менее, вы все равно можете делегировать событие на уровень TABLE и избежать более 15 000 обработчиков
  • 0
    Кроме того, у вас не было бы нескольких одинаковых идентификаторов - я думаю, вы могли бы иметь несколько Смитов в своей таблице
Показать ещё 5 комментариев
Теги:

1 ответ

3
Лучший ответ

Не прикрепляйте обработчик событий к каждой ячейке. Он очень неэффективен и потребляет много памяти.

Используйте функцию барботирования событий и присоедините обработчик к элементу более высокого уровня, к таблице в этом случае.

попробуйте что-нибудь вроде

$("table#tblid").on("click", "td.tdTime", function(e) { 
    console.log("Td clicked", e);
    console.log(e.target);
});

ПРИМЕЧАНИЕ. Как правильно сказано в комментарии (by @A.Wolf) ниже, это не является ярлыком для добавления всех обработчиков сразу. Это объявление только одного обработчика элемента таблицы, который содержит все элементы td. В таблице можно увидеть событие click на дочернем td из-за механизма, известного как "распространение событий" или "пузырение событий". Он использует гораздо меньше ресурсов, чем и меньше, чем подверженность ошибкам, чем добавление обработчиков к отдельным элементам. Он работает, даже если вы динамически добавляете элементы td позже в таблицу.

Проверьте этот jsFiddle: http://jsfiddle.net/BuddhiP/prv6y/

http://api.jquery.com/on/

  • 0
    Большой! Работает как шарм! Спасибо за это. Теперь он добавляет слушателя ко всем ячейкам в 3 мс! :))
  • 0
    @cheeZer Нет, он не добавляет прослушиватель для каждой ячейки, поэтому цель делегирования - избежать этого;) Но в любом случае вам нужно больше отображать столько данных одновременно. Каждый раз, когда вам придется манипулировать этими данными в DOM, вы будете вызывать проблемы. Вы должны использовать этот вид плагина и использовать пагинацию: datatables.net
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню