找到嵌套深度

时间:2010-08-24 11:37:00

标签: php jquery

所以,以这个html为例:

<ul>
    <li>
        <a href="#">Test</a>

        <ul>
            <li><a href="#">Test</a></li>
            <li><a href="#">Test</a></li>
            <li><a href="#">Test</a></li>
            <li><a href="#">Test</a></li>
        </ul>
    </li>
    <li>
        <a href="#">Test</a>

        <ul>
            <li><a href="#">Test</a></li>
            <li>
                <a href="#">Test</a>

                <ul>
                    <li><a href="#">Test</a></li>
                    <li><a href="#">Test</a></li>
                    <li><a href="#">Test</a></li>
                    <li><a href="#">Test</a></li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

我想找出这个结构的最大深度,在这个例子中它将是3,因为结构向下3级。但结构可以有任意深度。

使用DOM扩展的javascript / jquery解决方案或基于PHP的解决方案都可以。我真的不能想到这样做的好方法。也许有一个xpath表达式完全符合我的要求?

编辑:澄清:在这种情况下,深度是ul元素的最大嵌套,在本例中为3。

4 个答案:

答案 0 :(得分:4)

如果您不想指定最低选择器,这将为您提供最大嵌套级别数:

var n = 0

$('ul').each(function(i){ 
    if (($(this).parents('ul').length + 1) > n) { n = $(this).parents('ul').length + 1; }
});

编辑:变量n包含嵌套级别的数量,因此对于上面的示例,3。

答案 1 :(得分:4)

即使你已经接受了答案,我也会把它扔出去,因为我觉得它会更有效率。

试一试: http://jsfiddle.net/3haSq/

Math.max.apply(null, $('ul:not(:has(ul))').map(function() {
    return $(this).parents('ul').length;
}).get()) + 1;
  • $('ul:not(:has(ul))')仅关注嵌套<ul>
  • <ul>元素
  • .map().get()为您提供其父<ul>元素
  • 的数量数组
  • 原生Math.max()找到最大值
  • 在末尾添加+1以表示最初选择的<ul>

修改

我们执行Math.max.apply()而不是Math.max()的原因非常简单。

通常Math.max()需要多个int个参数,如下所示:

Math.max(12, 23, 34);  // results in `34`

只要您事先确切知道有多少参数,这就没问题了。不是这里的情况。

通常,.apply()方法用于调用函数,但更改该函数调用的值this.apply()第一个参数是this的新值。在这里,我们传递null,因为我们真的不在乎价值是什么。

我们关心的.apply()的重要部分是第二个参数,它接受通常传递给函数的Array个参数。所以以上面的例子为例,我们会这样做:

Math.max.apply(null, [12,23,34]);  // Converts the Array to a list of arguments

正如您所看到的,这允许Math.max()接受一个int个数组,而不是几个逗号分隔的int

(有一种类似的方法称为.call(),其方式与原始函数相同。如:)

Math.max.call(null, 12,23,34);   // This version takes several arguments
                                 //     instead of one Array.

答案 2 :(得分:1)

“好”的方式是计算特定元素的父母。可以说,有一个id == foobar的锚,你可以做

$('#foobar').parents.length - 1

将返回父节点的数量,这也是深度。

“丑陋”的方式是一个递归函数,它会遍历标记中的每个元素,直到不再有child nodes为止。

答案 3 :(得分:1)

如果要指定根,则此递归函数将起作用。我在下面的例子中使用了“body”:

function Recurse($item, depth) {
    $item.each(function() {
        depth.count++;
        if (depth.count > depth.max) {
            depth.max = depth.count;
        }
        Recurse($(this).children(), depth);
    });
    depth.count--;
    return depth.max;
}


$(document).ready(function() {
    alert(Recurse($("body"), { count: 0, max:0 }));
}

此处还有这个小提琴:http://jsfiddle.net/RqHzf/