【问题标题】:How to properly filter divs by class using jQuery?如何使用 jQuery 按类正确过滤 div?
【发布时间】:2012-08-06 15:52:08
【问题描述】:

我正在过滤一个 ASP.NET 中继器,该中继器使用 jQuery 在客户端输出超过 2000 个 div。中继器的 ItemTemplate 包含一个 div (runat="server")。在转发器 OnItemDataBound 事件中,我有一些逻辑可以根据数据应用 css 类。然后,我有一些 id 与 css 类同名的链接,因此当单击链接时,jQuery 会隐藏中继器输出的所有没有匹配 id/类组合的 div。此外,在某些情况下,div 应用了多个类。

在我单击链接过滤 div 的前 2 次左右一切正常,但随后它被挂断,变得无响应。

jQuery:

$(document).ready(function () {
    $('#filters a').click(function (e) {
        e.preventDefault();
        if ($(this).attr('id') == 'all') {
            $('#divIssueMenu').children().show();
        }
        else {
            var filter = $(this).attr('id');
            $('#divIssueMenu').children().show();
            $('#divIssueMenu').children().not('.' + filter).hide();
        }
    });
});

并输出标记:

<div id='filters'>
    <a href='#' id="all" >All</a> | 
    <a href='#' id='filter1'>Filter 1</a> | 
    <a href='#' id='filter2'>Filter 2</a> | 
    <a href='#' id='filter3'>Filter 2</a> |
    and so on...
    <div class='clear'></div>
</div>
<div id="divIssueMenu">
    Menu

    <div id="rpMenu_divMenu_0" class="filter1">
       data here...
    </div>

    <div id="rpMenu_divMenu_1" class="filter2">
        more data...
    </div>

    <div id="rpMenu_divMenu_2" class="filter1 filter2">
        more data...
    </div>

    <div id="rpMenu_divMenu_3" class="filter1 filter2 filter3">
        more data...
    </div>


    and so on, about 2000+ records...
</div>

有什么方法可以提高效率吗?是这个问题吗? 提前致谢!

【问题讨论】:

  • 页面加载后#divIssueMenu的内容有没有变化?此外,您可以通过将 $(this).attr('id') 替换为 this.id 来节省每次点击的一些函数调用。
  • divIssueMenu 的内容在中继器的输出每次回发后都会重新创建,但所有过滤都发生在客户端。谢谢,我会试试 this.id

标签: jquery asp.net


【解决方案1】:

在性能方面,我很想缓存我的项目并基于此显示或隐藏

var $all = $('div','#divIssueMenu');
var $filter1 = $('div.filter1','#divIssueMenu');
var $filter2 = $('div.filter2','#divIssueMenu');
var $filter3 = $('div.filter3','#divIssueMenu');

然后您可以将过滤器放入关联数组中以将 id 分配给正确的集合

var filters = {all:$all, filter1:$filter1, filter2:$filter2, filter3:$filter3}

点击代码将是:

$('#filters a').click(function (e) {
    e.preventDefault();
    var id = $(this).attr('id');
    $all.hide();
    filters[id].show();
});

这样做的好处是不必在每次点击时评估选择器。

现场示例:http://jsfiddle.net/maZD7/

【讨论】:

  • 我将其标记为答案,因为它似乎是最快的方法,但事实证明,与其他浏览器相比,chrome 存在问题。 Faust 和 Steve Campbell - 这两个答案都比我的解决方案更有效。谢谢!!
【解决方案2】:

通过在 click 事件之外执行一次来减少为 $('#divIssueMenu').children() 创建 jQuery 集合的调用次数,并在事件内部引用该 var(下面块中的第一行)。

然后在点击事件中,不要打开所有组并有选择地关闭一些组,而是使用jQuery的toggle()函数来判断每个组是否应该出现:

var $allGroups = $('#divIssueMenu').children();

$(document).ready(function () {
    $('#filters a').click(function (e) {
        e.preventDefault();
        if (this.id == 'all') {
            $allGroups.show();
        }
        else {
            var filter = this.id;
            $allGroups.each(function(){
                $(this).toggle($(this).hasClass(filter));
            });
        }
    });
});

【讨论】:

    【解决方案3】:

    很难说到底是什么问题,所以正如其他人所做的那样,我可以指出看起来不太理想的事情。

    我喜欢浮士德关于效率和可读性的答案,但它是quicker to use a class to show or hide。因此,不要切换,而是添加或删除一个类:

    var $allGroups = $('#divIssueMenu').children();
    
    $(document).ready(function () {
        $('#filters a').click(function (e) {
            e.preventDefault();
            if (this.id == 'all') {
                $allGroups.show();
            }
            else {
                $allGroups.removeClass('visible');
                var filter = this.id;
                $allGroups.hasClass(filter).addClass('visible');
            }
        });
    });
    

    ...css 看起来像这样:

    #divIssue>div {display:none;}
    #divIssue>div.visible {display:block;}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-06
      • 1970-01-01
      • 1970-01-01
      • 2022-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多