选择类时缓慢的jQuery选择器

时间:2014-03-20 09:29:28

标签: javascript jquery

我有下表。

<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,000ms才能将监听器添加到每个单元格,Chrome仍然需要大约3,000ms。在很多网站上,建议使用id作为选择器来加快速度,但是你可以看到我已经使用了id,在这种情况下我几乎不可能使用这些id,因为这个表是 - 再次 - 更多比简单的例子复杂。

你有什么建议加快这个过程?在另一篇文章中我读了一篇关于给选择器提供上下文的提示,我应该给表行一个连续的id(“trTime1”,“trTime2”,...),然后记住这些行的数量,然后再做一个for循环添加监听器?类似的东西:

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

感谢您的帮助,伙计们!

编辑:正如A. Wolff正确地提到的,15,000个单元格太多而无法显示 - 我想这样补充说,大多数单元格在开始时都是隐藏的。所以在页面加载后我对性能没有任何问题。 (但遗憾的是,无论如何,细胞都需要听众)

1 个答案:

答案 0 :(得分:3)

不要将事件处理程序附加到每个单元格。它的效率非常低,并且消耗大量内存。

使用事件冒泡功能并将处理程序附加到更高级别的元素,在这种情况下附加到表。

尝试类似

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

注意:正如下面的注释(@ A.Wolf)中正确提到的,这不是一次添加所有处理程序的快捷方式。这个广告只包含一个包含所有td元素的table元素的处理程序。表可以看到子td上的click事件,因为称为“事件传播”或“事件冒泡”的机制。与向单个元素添加处理程序相比,它使用的资源少得多,并且容易出错。即使您稍后在表上动态添加td元素,它也能正常工作。

检查这个jsFiddle:http://jsfiddle.net/BuddhiP/prv6y/

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