如何选择最里面的元素?

IT技术 javascript jquery html
2021-03-08 07:09:17

在 jQuery 中,我如何尽可能地下降到 HTML 树中?

为简单起见,我只有一条向下的路径。

(相关但奖励:我如何找到具有多个向下路径的最深元素?)

<html>  
  <table id="table0">  
    <tr>  
      <td id="cell0">  
        <div class"simple">  I want to change this information </div>  
      </td>
    </tr>  
  </table>  
</html>

我想更改名为cell0的单元格最里面的 HTML,但我不一定知道里面所有类的名称。在不知道这些名称的情况下,是否可以选择这么远?

非常感谢!

6个回答

对于单个路径,只需找到没有子节点的元素:

$('body *:not(:has("*"))');

或者,在您更具体的情况下 $('#cell0 *:not(:has("*"))');

对于多个路径 - 如果有多个同样嵌套的节点怎么办?此解决方案将为您提供具有最高祖先数量的所有节点的数组。

var all = $('body *:not(:has("*"))'), maxDepth=0, deepest = []; 
all.each( function(){ 
    var depth = $(this).parents().length||0; 
    if(depth>maxDepth){ 
        deepest = [this]; 
        maxDepth = depth; 
    }
    else if(depth==maxDepth){
        deepest.push(this); 
    }
});

同样,在您的情况下,您可能想要获取表格单元格的最深元素,因此您又回到了单行模式:

$('#table0 td *:not(:has("*"))');

- 这将返回一个 jQuery 对象,其中包含表中每个单元格的所有最里面的子节点。

我会通过一个递归函数来做到这一点:

// Returns object containing depth and element
// like this: {depth: 2, element: [object]}
function findDeepestChild(parent) {

    var result = {depth: 0, element: parent};

    parent.children().each(
        function(idx) {
            var child = $(this);
            var childResult = findDeepestChild(child);
            if (childResult.depth + 1 > result.depth) {
                result = {
                    depth: 1 + childResult.depth, 
                    element: childResult.element};
            }
        }
    );

    return result;
}

对于 jQuery,这个问题有一个简单而好的答案。但是,我一直在寻找没有它的优雅解决方案。由于:has尚不支持任何浏览器,我在这里想出了这个。

Array.from( document.querySelectorAll( 'body *' ) )
  .filter( e => !e.children.length );

好吧,从您不知道这个“最深”节点在哪里的基础开始,您可以执行以下操作:

$.fn.deepest = function() {
  var depth = 0;
  this.find('*').each(function() {
    var d = $(this).parents().length;
    depth = Math.max(d, depth);
  });
  return this.find('*').filter(function() {
    return this.parents().length === depth;
  });
});

然后

var $deepest = $('body').deepest();

将(除了可能在我的代码中的 12 个错误)将是最深元素集的 jQuery 对象。

编辑- 我的十几个错误之一是这没有考虑起始节点的深度 - 这将是一个弄清楚的技巧。重构它可能会更好,以便它找到最初选择的列表中最深的:

$.fn.betterDeepest = function() {
  var depth = 0;
  this.each(function() {
    depth = Math.max(depth, $(this).parents().length);
  });
  return this.filter(function() { return $(this).parents().length === depth; });
});

并在页面上获得最深的内容:

var deepest = $('*').betterDeepest();

使用单一路径:

var elem = $('#table0'),
    next;
while ((next = elem.children(':first')).length > 0)
  elem = next;
// elem now points to the deepest child of table0

如果我有时间,我会用多条路径的代码更新我的答案。

@sova:next不是 JavaScript 中的关键字。由于此站点上的语法高亮器支持多种语言,因此有时会高亮显示其他语言的单词。
2021-04-29 07:09:17
甜的。我不知道下一个关键字。
2021-05-07 07:09:17
@sova - 没有next关键字。这里它只是一个变量名。
2021-05-18 07:09:17