最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to get all nested elements with jQuery? - Stack Overflow

programmeradmin4浏览0评论

Is there some method in jQuery to get all nested children? I mean plete collection from all nested levels so that I do not need to call function recursively.

Here is my function

$.fn.extend({
  pressElementsWidth: function() {
    var range = { min: 9999, max: 0 };
    console.log( $(this).contents() );

    $(this).contents().filter(
      function() { 
        if (this.nodeType == 3 )
           return this.nodeValue && this.nodeValue.replace(/\s{1,6}/,'') ? $(this) : null;
        else
           return this.nodeName.match(/IMG|A|GROUP|FIELDSET|INPUT|SELECT|TEXTAREA|BUTTON|SUBMIT/) ? $(this) : null;
      }).each(function(e) {
        var left = $(this).position();
        if (p.left < range.min ) 
          range.min = p.left;
        var right = p.left + $(this).width;
        if ( right > range.max ) 
          range.max = right;
    });
    var max_width = range.max - range.min; 
    $(this).contents().filter(
      function() 
      { 
        if (this.nodeType == 3 )
           return this.nodeValue && this.nodeValue.replace(/\s{1,6}/,'') ? $(this) : null;
        else
           return this.nodeName.match(/IMG|A|GROUP|FIELDSET|INPUT|SELECT|TEXTAREA|BUTTON|SUBMIT/) ? $(this) : null;
      }).each(function(e) {
        $(this).css("max-width:", max_width );
    });
  }
});
window.onload = function() {  
  $("div.column-right-outer")pressElementsWidth();
};

So I need to get all elements inside the div.column-right-outer. You can test this code on this page, just save it and include jQuery and the code above. For example in the Blog Archive, there is huge list of links and I need to get all the links and all the visible text which is under the right column. If there would be images or form elements I need them in the collection too.

Results of recursion and $(node).find("*") are about 10.000-16.000 and extremely slow performance.

Is there some method in jQuery to get all nested children? I mean plete collection from all nested levels so that I do not need to call function recursively.

Here is my function

$.fn.extend({
  pressElementsWidth: function() {
    var range = { min: 9999, max: 0 };
    console.log( $(this).contents() );

    $(this).contents().filter(
      function() { 
        if (this.nodeType == 3 )
           return this.nodeValue && this.nodeValue.replace(/\s{1,6}/,'') ? $(this) : null;
        else
           return this.nodeName.match(/IMG|A|GROUP|FIELDSET|INPUT|SELECT|TEXTAREA|BUTTON|SUBMIT/) ? $(this) : null;
      }).each(function(e) {
        var left = $(this).position();
        if (p.left < range.min ) 
          range.min = p.left;
        var right = p.left + $(this).width;
        if ( right > range.max ) 
          range.max = right;
    });
    var max_width = range.max - range.min; 
    $(this).contents().filter(
      function() 
      { 
        if (this.nodeType == 3 )
           return this.nodeValue && this.nodeValue.replace(/\s{1,6}/,'') ? $(this) : null;
        else
           return this.nodeName.match(/IMG|A|GROUP|FIELDSET|INPUT|SELECT|TEXTAREA|BUTTON|SUBMIT/) ? $(this) : null;
      }).each(function(e) {
        $(this).css("max-width:", max_width );
    });
  }
});
window.onload = function() {  
  $("div.column-right-outer").pressElementsWidth();
};

So I need to get all elements inside the div.column-right-outer. You can test this code on this page, just save it and include jQuery and the code above. For example in the Blog Archive, there is huge list of links and I need to get all the links and all the visible text which is under the right column. If there would be images or form elements I need them in the collection too.

Results of recursion and $(node).find("*") are about 10.000-16.000 and extremely slow performance.

Share Improve this question edited Sep 1, 2016 at 17:00 John Boe asked Sep 1, 2016 at 15:16 John BoeJohn Boe 3,62110 gold badges43 silver badges78 bronze badges 2
  • What are you planning on doing with all of this info? – ntgCleaner Commented Sep 1, 2016 at 15:23
  • This is a function which should calculate "plete content width" of the column (wrapper). In this particular page it is not perfect example. But if you would remove the column "Popular Posts", than it should press width of the column so that the redundant width is removed. – John Boe Commented Sep 1, 2016 at 15:28
Add a ment  | 

5 Answers 5

Reset to default 4

method in JQuery to get all nested children

You can use the all selector : "*"

Combine this with the parent element in any number of ways:

var nodes = $("div.column-right-outer *");
var nodes = $("div.column-right-outer > *");
var nodes = $("div.column-right-outer").find("*");

If you need all items, then don't apply a parent:

var nodes = $("*")

Example fiddle: https://jsfiddle/9xted244/


.contents() is similar to "*" and will include text and ments

What about element.childNodes ?

https://developer.mozilla/en-US/docs/Web/API/Node/childNodes

EDIT

childNodes returns a collection of node, including text nodes. Every tabulation and line break are text nodes.

I would suggest using jQuery's contents() method. It is used for this exact purpose, if I am not mistaken.

See the API here: https://api.jquery./contents/

Are you calling it in a frame load?

$("#frame").load(function() {

    ... contents method

});

maybe write a function that dives into each thing?

function dive(that) {
    var element_width = that.width();
    array_width.push(that.width());
    if(that.children().length > 0){
        that.children().each(function(){
            dive($(this));
        });
    }
}

var array_width = [];
dive($('div.column-right-outer'));

This should push the widths of your elements into an array. I haven't tested it, but maybe this is a start?

Also, not sure how fast/slow it would be.

Here is the result of my tests.

1) console.log($('div.column-right-outer').contents()); gives three results

2.1) recursive call with contents() produces about 27.000 of results +/- extremely slow performance. 2.2) find("*") is similar, same count of results and extremely slow performance

3) console.log($('div.column-right-outer').find("*").filter(":v‌​isible")); produces 224 results. This is correct. The performance seems better but I think the find("*") still can reduce performance.

Now, the code of updated function:

<script src="https://ajax.googleapis./ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
$.fn.extend({
  pressElementsWidth: function() {
    var range = { min: 9999, max: 0 };
    $(this).find("*").filter(":visible").filter(
      function() { 
       if (this.nodeType == 3 )
         return this.nodeValue && this.nodeValue.replace(/\s{1,6}/,'') ? $(this) : null;
       else
         {
         var result = this.nodeName.match(/IMG|A|GROUP|FIELDSET|INPUT|SELECT|TEXTAREA|BUTTON|SUBMIT/);
         return this.nodeName.match(/IMG|A|GROUP|FIELDSET|INPUT|SELECT|TEXTAREA|BUTTON|SUBMIT/) ? $(this) : null;
         }
      }).each(function(e) {
        var left = $(this).position();
        if (p.left < range.min ) 
          range.min = p.left;
        var right = p.left + $(this).width;
        if ( right > range.max ) 
          range.max = right;
    });
    var max_width = range.max - range.min; 
    $(this).find("*").filter(":visible").filter(
      function() 
      { 
       if (this.nodeType == 3 )
         return this.nodeValue && this.nodeValue.replace(/\s{1,6}/,'') ? $(this) : null;
       else
         return this.nodeName.match(/IMG|A|GROUP|FIELDSET|INPUT|SELECT|TEXTAREA|BUTTON|SUBMIT/) ? $(this) : null;
      }).each(function(e) {
        $(this).css("max-width:", max_width );
    });
  }
});
window.onload = function() {  
  $("div.column-right-outer").pressElementsWidth();
  // console.log($('div.column-right-outer').find("*").filter(":visible"));
};
</script>

To test it just save this page and insert the code above into the file.

Note: the function is still not fully working because it should enter to the function on line #16 where is var left =... this does not happen. It returns $(this) when result of the match is array. This happens when .nodeName is "A". But still it does not enter to the next function after return from here. I also tried to return this. Any idea how to fix this?

发布评论

评论列表(0)

  1. 暂无评论