Skip to content Skip to sidebar Skip to footer

JQuery Distinct Descendants (filter Out All Parents In Result Set)

I needed a method to filter out all elements that are parents of other elements in the result set. I tried to write a plugin: jQuery.fn.distinctDescendants = function() { var n

Solution 1:

Why aren't you using jQuery('body > input') instead?

You can use the following (verbose) code to achieve what you want; it should work as drop-in replacement of your plugin code.

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;
};

Solution 2:

Your method seems OK but your example is perhaps wrong. You said -

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

I get the (wrong) result:

[body.contact-page, textarea, textarea]

How come you are getting textarea if that is not there in the selector? Also be careful using this method. Remember -

jQuery('div, input').distinctDescendants(); means some input are inside the div under consideration and some are outside. Though the result is not unpredictable but it is apparently difficult to guess. So most of the time try use selector having class name or id.

Do let us know your feedback ... I feel the function is ok.


Solution 3:

I think this is what you are expecting for

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

or may be rather

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

and this will return only the text areas(as you want in the example)

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

UPDATE

so you want something like this

var elems = 'textarea';

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

which returns

[textarea, textarea]

Post a Comment for "JQuery Distinct Descendants (filter Out All Parents In Result Set)"