如何在过滤列表中使用第n子节点

How to use nth-child on a filtered list?

本文关键字:子节点 过滤 列表      更新时间:2023-09-26

我正在从数据库中提取图像/项目列表,并根据类别过滤它们。

设计要求是平铺/马赛克布局,第7项上有一个大正方形,第8项上有一个更大的矩形,在所有过滤器上。这意味着较大的方块不能以不同的顺序排列。

目前我的方法是使用第n个子选择器从项目列表中选择第7和第8个:

/* create big item block */
.grid-item:nth-child(7n) { 
  height: 24em;
  width: 50%; 
}
/* create rectangle item block */
.grid-item:nth-child(8n) { width: 50%; }

这是一个问题,因为它只影响整个列表。在选择按钮/类别后,我如何定位过滤列表中的第7和第8项?

这是一个我试图为所有视图过滤器实现的正确布局的代码依赖。我试图实现这种相同的布局,但基于过滤器不同的项目。如果你选择"thank you"类别,你可以看到大方块被拉到列表的第三位,由于第n个子选择器,它仍然是一个大方块。

http://codepen.io/H0BB5/pen/BLNLWy

问题是双重的:

  • 同位素不会去除过滤掉的物质,而是用display:none隐藏它们。因此,项目在CSS中仍然可以被nth-child()选择器选择。
  • 项目的大小调整需要在网格重新排列之前执行,因此在grid.isotope({filter: ...})被调用之前。

因此,CSS不能自己完成这项工作。需要更多的javascript。

一种方法是:

  • 设置一个'arrangeComplete'事件处理程序来调整网格项目的大小,并调用grid.isotope()来重新排列它们,
  • 调用grid.isotope({ filter: ... })并允许事件处理程序在过滤器被应用后触发。

这还可以,但是用户会看到双重排列。

// bind filter button click
$('#filters').on('click', 'button', function() {
    var filterValue = $(this).attr('data-filter');
    grid.one('arrangeComplete', function(event, laidOutItems) {
        // Triggered after a layout and all positioning transitions have completed.
        $('.grid .grid-item').filter(':visible').removeClass('big rectangle')
            .eq(6).addClass('big') // the 7th item
            .end()
            .eq(7).addClass('rectangle'); // the 8th item
        grid.isotope(); // re-trigger isotope
    });
    grid.isotope({ filter: filterFns[filterValue] || filterValue });
}).find('button').eq(0).trigger('click');// trigger click on default button to initialize everything.

为了更好的视觉效果,你可以聪明一点:

  • 手动"预应用"过滤器,不应用同位素的过滤器,通过过滤包含网格中所有项目的jQuery集合,
  • 仍然在jQuery集合中,选择第7/8个项目(从那些可见)并调整它们的大小,
  • 最后,再次使用相同的过滤器,调用grid.isotope({filter: ...})来重新排列网格。

因此,网格只重新排列一次,视觉效果会更令人愉悦。

幸运的是,jQuery链接使得代码相当简单:

// bind filter button click
$('#filters').on('click', 'button', function() {
    var filterValue = $(this).attr('data-filter');
    grid.find('.grid-item')
        .removeClass('big rectangle')
        .filter(filterFns[filterValue] || filterValue)
        .eq(6).addClass('big') // the 7th item
        .end()
        .eq(7).addClass('rectangle') // the 8th item
    grid.isotope({ filter: filterFns[filterValue] || filterValue });
}).find('button').eq(0).trigger('click');// trigger click on default button to initialize everything.

在这两种方法中,替换两个'。样式表中的Grid-item:n -child'指令,使用:

.grid-item.big { 
  height: 24em;
  width: 50%; 
}
.grid-item.rectangle { width: 50%; }

注意:如果要只设置第7/8项的样式,而不是第15/16、23/24项等,不要使用n -child