如何使用jQuery获取所有嵌套元素?

时间:2016-09-01 15:16:28

标签: javascript jquery html dom

jQuery中是否有一些方法可以获取所有嵌套子元素?我的意思是从所有嵌套级别完成集合,这样我就不需要递归调用函数。

这是我的功能

$.fn.extend({
  compressElementsWidth: 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").compressElementsWidth();
};

所以我需要将所有元素都放在div.column-right-outer中。您可以在this page上测试此代码,只需保存它并包含jQuery和上面的代码。例如,在博客存档中,有大量的链接列表,我需要获取所有链接以及右栏下的所有可见文本。如果有图像或表单元素,我也需要它们在集合中。

enter image description here

递归和$(node).find(“*”)的结果大约是10.000-16.000并且性能非常慢。 enter image description here

5 个答案:

答案 0 :(得分:3)

  用于获取所有嵌套子级的

方法

您可以使用all selector:“*”

以任意多种方式将其与父元素结合使用:

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

如果您需要所有项目,请不要申请父母:

var nodes = $("*")

示例小提琴:https://jsfiddle.net/9xted244/

.contents()类似于“*”,将包含文字和评论

答案 1 :(得分:0)

element.childNodes怎么样?

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

修改

childNodes返回节点集合,包括文本节点。每个制表和换行符都是文本节点。

答案 2 :(得分:0)

我建议使用jQuery的contents()方法。如果我没有记错的话,它就是用于这个目的。

请在此处查看API:https://api.jquery.com/contents/

你是在帧加载中调用它吗?

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

    ... contents method

});

答案 3 :(得分:0)

也许写一个潜入每件事的功能?

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'));

这应该将元素的宽度推入数组中。我还没有测试过,但也许这是一个开始?

另外,不确定它会有多快/多慢。

答案 4 :(得分:0)

这是我测试的结果。

1)console.log($('div.column-right-outer').contents()); 给出了三个结果

2.1)使用contents()的递归调用产生大约27.000个结果+/-极慢的性能。 2.2)find(“*”)是相似的,相同的结果数和极慢的性能

3)console.log($('div.column-right-outer').find("*").filter(":v‌​isible")); 产生 224 结果。这是对的。性能似乎更好,但我认为find(“*”)仍然会降低性能。

现在,更新功能的代码:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
$.fn.extend({
  compressElementsWidth: 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").compressElementsWidth();
  // console.log($('div.column-right-outer').find("*").filter(":visible"));
};
</script>

要测试它,只需保存this page并将上面的代码插入文件中。

注意:该函数仍未完全正常工作,因为它应该进入第16行的函数,其中var left = ...这不会发生。当匹配的结果是数组时,它返回$(this)。当.nodeName为“A”时会发生这种情况。但是从这里返回之后它仍然没有进入下一个功能。我也试着回复这个。知道如何解决这个问题吗?