如何使用 jQuery 和 detach() 从 DOM 中过滤元素

How to filter elements out of DOM using jQuery and detach()

我正在使用:

$('.filter__selector').change(function(){
var sel = $(this).val();
$('.filterItem').hide();
    //console.log(sel);
  if(sel != "all"){
    $('main').find('.projects__entry').hide();
    $('main').find('.' + sel).show();
  }
  else {
    $('main').find('.projects__entry').show();
  }
}
);

使用 select 下拉列表过滤列表项,效果很好。问题是我正在使用 &:nth-child(3n+3) 以不同方式设置每三个列表项的样式。

虽然 hide() 从屏幕上删除了项目,但它并没有从 DOM 中删除它们,我的 css 被搞砸了。作为额外的困难,如果 select 下拉列表发生变化,我想将它们切换回来。

为澄清起见,我创建了一个 fiddle:https://jsfiddle.net/9wtt4fge/2/ - 第三列中的项目应始终使用蓝色边框,前两列中的项目必须为红色。

我已经找到了 detach() 方法和这个 question/answer 但我无法让它工作。

感谢任何帮助!

分离方法是有效的解决方案,但问题的第二部分是,当你想将它重新附加到 dom 时,你必须知道在哪里,所以你必须跟踪哪里你想插入它。 您有两种选择,您可以依靠一个对象来保持元素有序,并且您必须通过循环分离并重新插入所有元素,或者您可以依靠可以在您之前插入的注释元素dom 元素。

//create comments nodes to keep track of order
let projectEntryElements = $('main .projects__entry');
projectEntryElements.each(function(){
    let commentDom = $('<!--filter-track-comment-->').insertBefore(this);
    $(this).data('commentDom',commentDom);
});

$('.filter__selector').change(function(){
    let sel = $(this).val();
    $('.filterItem').hide(); //I don't know if you want to hide it or detach it so I let it as it was in your original code
    if(sel!="all"){
        projectEntryElements.detach();
        projectEntryElements.filter('.' + sel).each(function(){
            $(this).data('commentDom').after(this); //re-insert this after the comment node
        });
    }
    else {
        projectEntryElements.each(function(){
            $(this).data('commentDom').after(this); //re-insert this after the comment node
        });
    }

});

此示例假设“.projects__entry”已加载到此脚本第一部分之前的 dom 中, 你必须使它适应你的用例(如果你想要复古兼容,你也可以用 var 替换 let 关键字)