JQuery 非重复后代(筛选出结果集中的所有父项)

JQuery distinct descendants (filter out all parents in result set)

本文关键字:集中 结果 后代 筛选 JQuery      更新时间:2023-09-26

我需要一种方法来过滤掉结果集中其他元素的父级的所有元素。我尝试编写一个插件:

jQuery.fn.distinctDescendants = function() {
    var nodes = [];
    var result = this;
    jQuery(result).each(function() {
        var node = jQuery(this).get(0);
        if(jQuery(node).find(result).length == 0) {
            nodes.push(node);
        }
    });
    return nodes;
};

当我在此示例页面上运行以下命令时:

jQuery('body, textarea').distinctDescendants();

我得到(错误的)结果:

[body.contact-page, textarea, textarea]

这是错误的,因为 body 是结果中至少一个其他元素(两个文本区域)的父元素。因此,预期结果将是:

[textarea, textarea]

这是怎么回事?

你为什么不使用jQuery('body > input')

您可以使用以下(详细)代码来实现您想要的内容;它应该作为插件代码的直接替换。

jQuery.fn.distinctDescendants = function() {
    var nodes = [];
    var parents = [];
    // First, copy over all matched elements to nodes.
    jQuery(this).each(function(index, Element) {
        nodes.push(Element);
    });
    // Then, for each of these nodes, check if it is parent to some element.
    for (var i=0; i<nodes.length; i++) {
        var node_to_check = nodes[i];
        jQuery(this).each(function(index, Element) {
            // Skip self comparisons.
            if (Element == node_to_check) {
                return;
            }
            // Use .tagName to allow .find() to work properly.
            if((jQuery(node_to_check).find(Element.tagName).length > 0)) {
                if (parents.indexOf(node_to_check) < 0) {
                    parents.push(node_to_check);
                }
            }
        });
    }
    // Finally, construct the result.
    var result = [];
    for (var i=0; i<nodes.length; i++) {
        var node_to_check = nodes[i];
        if (parents.indexOf(node_to_check) < 0) {
            result.push(node_to_check);
        }
    }
    return result;
};

你的方法似乎没问题,但你的例子可能是错误的。你说——

jQuery('body, input').distinctDescendants();

我得到(错误的)结果:

[body.contact-page, textarea, textarea]

如果选择器中没有文本区域,您为什么会得到文本区域?使用此方法时也要小心。记得-

jQuery('div,

input').distinctDescendants(); 表示一些输入在正在考虑的div 内部,而一些在外部。虽然结果并非不可预测,但显然很难猜测。所以大多数时候尝试使用具有类名或 id 的选择器。

请让我们知道您的反馈...我觉得功能还可以。

我认为这就是你所期望的

jQuery('body, input').filter(function(){if($(this).children().length >0) return false; else return true; })

或者可能是相当

jQuery('body, input, textarea').filter(function(){if($(this).children().length >0) return false; else return true; })

这将仅返回文本区域(如示例中所示)

jQuery('body, textarea').filter(function(){if($(this).children().length >0) return false; else return true; })

更新

所以你想要这样的东西

var elems = 'textarea';
jQuery('body, '+ elems )
      .filter(function(){
           if($(this).find(elems ).length >0) 
               return false; 
           else return true; 
       })

返回

[textarea, textarea]