【问题标题】:Convert .each() because it's slow转换 .each() 因为它很慢
【发布时间】:2014-07-07 16:12:30
【问题描述】:

我正在使用 .each 函数来隐藏/显示表格的列。但问题是 IE 中的代码非常慢。在互联网上搜索后,我发现这可能是因为我的 .each() 函数和 $(this)。

有关我为什么使用此代码的更多信息,您可以查看此帖子:Hide/show column

这是我的旧代码: 在页面上包含 JQuery.min.js

javascript:

$(function () {
    $('table th').each(function (_id, _value) {
    if(_id > 2){
        if($(this).find("a").text()){
            $('<span class="ShowHide"><div style="width:175px; display: inline-block;">- '+$(this).find("a").text()+'</div></span>').appendTo($("#togglers")).click(function (e) {
                $('table td:nth-of-type(' + parseInt(_id + 1) + '),table th:nth-of-type(' + parseInt(_id + 1) + ')').toggle();
                e.preventDefault();
            });
        }
        else{
            if($(this).find("div").text()){
                $('<span class="ShowHide"><div style="width:175px; display: inline-block;">- '+$(this).find("div").text()+'</div></span>').appendTo($("#togglers")).click(function (e) {
                $('table td:nth-of-type(' + parseInt(_id + 1) + '),table th:nth-of-type(' + parseInt(_id + 1) + ')').toggle();
                e.preventDefault();
                });
                }
            }
        }
    });

});

HTML:

<div id="togglers">Show/Hide columns<br/></div>

我尝试使用此代码转换我的 javascript(来源:jQuery very slow in IE),但我认为我的 i(或 _id)和 _value 仍然存在问题...

$(function () {
var items = $('table th');
var $currentItem;

    for (var i = 0, j = items.length; i < j; i++) {
        $currentItem = $(items[i]); // in place of $(this)
        function (i, _value) {
            if(i > 2){
                if($currentItem.find("a").text()){
                    $('<span class="ShowHide"><div style="width:175px; display: inline-block;">- '+$currentItem.find("a").text()+'</div></span>').appendTo($("#togglers")).click(function (e) {
                        $('table td:nth-of-type(' + parseInt(i + 1) + '),table th:nth-of-type(' + parseInt(i + 1) + ')').toggle();
                        e.preventDefault();
                    });
                }
                else{
                    if($currentItem.find("div").text()){
                    $('<span class="ShowHide"><div style="width:175px; display: inline-block;">- '+$currentItem.find("div").text()+'</div></span>').appendTo($("#togglers")).click(function (e) {
                    $('table td:nth-of-type(' + parseInt(i + 1) + '),table th:nth-of-type(' + parseInt(i + 1) + ')').toggle();
                        e.preventDefault();
                    });
                    }
                }
            }
        }
    }
});

我可能需要使用其他代码。欢迎任何建议! Tnx。

【问题讨论】:

  • 速度慢的原因是你的代码一团糟。例如,当您知道只需要第四个 TH 元素及以上元素时,为什么还需要迭代?
  • 你为什么要parseInt(_id + 1)_id1 都已经是数字了。您需要做的就是:(_id + 1) 和括号只是防止变量被连接到字符串本身,而不是加在一起。
  • 查看其他帖子为什么我使用此代码... (stackoverflow.com/questions/24568739/hide-show-column/24569240)
  • @endeka jQuery 增加了一些开销。但真正的问题是你使用它的方式。 :)
  • @YuryTarabanko 最后一个问题:我想“分组”不同的列,例如颜色和数字将是顶部的“更多信息”。因此,您会在顶部看到“更多信息”,如果单击它,则可以看到颜色和编号列。这可能吗?

标签: javascript jquery performance each


【解决方案1】:

性能问题与.each 无关。 DOM 比您选择的任何迭代集合的方式慢几十倍。

您可以让 CSS 为您完成,而不是在每次切换时迭代表。 Demo.

$(function() {
    var togglers = $('#togglers'), //cache toggler ref
        addToggler = function(idx, text) {
            togglers.append('<span class="toggler" data-id="' 
                              + idx + '">' + text + '</span>');    
        },
        table = $('#table'), //cache table ref
        columns = 0;

    //generate styles for 100 columns table :)
    (function generateStyleSheet(len){
        var styles = [], i = 0;

        for(; i < len; i++) {
            styles.push('.hide-' + i + ' .column-' + i + ' {display: none;}') ;
        }

        $('<style>' + styles.join('\n') + '</style>').appendTo(document.body);
    }(100)) 

    //bind on click once using event delegation
    togglers.on('click', '.toggler', function(e){
        var id = $(e.target).toggleClass('pressed').data('id');
        table.toggleClass('hide-' + id);
    }); 

    //generate all togglers and count em
    table.find('th').each(function(idx, header){ 
        header = $(header);
        addToggler(idx, header.text()); //make toggler
        header.addClass('column-' + idx); //add class column-i
        columns++;
    });

    //add column-i class to tds
    table.find('td').each(function(idx, td) { 
        $(td).addClass('column-' + (idx%columns));
    });

});

【讨论】:

  • 我正在尝试使用您的代码,但由于某种原因,我没有进入函数“table.find('th').each(function(idx, header)”。试图添加一些警报以查看我是否要进入每个功能...
  • jsfiddle.net/tarabyte/s8Qds - 在这里工作。如果您在其他地方尝试此代码,请确保您确实有 ID 为 table 的表:)
  • 确实,这就是问题所在。但我没有事先的身份证。我知道该表是 ID 为 ctl00_MSO_ContentDiv 的 div。我需要在 +50 个页面上使用此代码,并且每个页面上的 id 都不同...
  • @endeka 好吧,使用任何可以找到所需表格的选择器。你甚至可以通过将这段代码概括一下来制作一个插件。
  • @endeka 更多 OOP 示例,允许您按名称隐藏列。 jsfiddle.net/tarabyte/s8Qds/3
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-27
  • 1970-01-01
  • 2018-06-15
相关资源
最近更新 更多