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

Posted

技术标签:

【中文标题】如何使用 jQuery 和 detach() 从 DOM 中过滤元素【英文标题】:How to filter elements out of DOM using jQuery and detach() 【发布时间】:2017-04-12 10:50:41 【问题描述】:

我正在使用:

$('.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 下拉菜单发生更改,我想将它们重新切换回来。

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

我已经找到了detach() 方法和这个问题/答案How to toggle elements in and out of DOM using jQuery detach() method?,但我无法让它发挥作用。

感谢任何帮助!

【问题讨论】:

您可以从 DOM 中删除该项目吗?还是只隐藏它们以便之后重复使用? 我只想“隐藏”它们并在 select 字段更改时重复使用它们。 【参考方案1】:

分离方法是有效的解决方案,但问题的第二部分是,当你想将它重新附加到 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 关键字)

【讨论】:

就像一个魅力!也许你可以再帮我做一件事。在我也在使用的旧版本中: 就像一个魅力!也许你可以再帮我做一件事。在旧版本中,我也在使用:`$('main').find('.' + sel).show();` 我正在尝试`$('main').find('.' + sel) .data('commentDom').after(this);` 但它不起作用 你必须对每个节点进行操作` $('main').find('.' + sel).each(function() $(this).data('commentDom' )。在这之后); ); `

以上是关于如何使用 jQuery 和 detach() 从 DOM 中过滤元素的主要内容,如果未能解决你的问题,请参考以下文章

jQuery中的remove()detach()和empty()的区别

在 .detach() 之后恢复 jQuery 对象

转载JQuery 中empty, remove 和 detach的区别

[ jquery 文档处理 empty() remove([expr]) detach([expr]) ] 此方法用于把所有匹配的元素移除

jQuery中的detach()方法解析

jQuery基础:remove()与 detach()区别