JS:如何根据需要自动上升 "parentNode" 次

JS: How to automate going up "parentNode" as many times as needed

假设我有一个名为 Z.Zthat is a sub-sub-sub... child of adivcalledBwhich is a child of adiv 的 div called一个`。

BZ的所有块都设置为display=noneA可见)。

如果我单击链接到块 Z 的锚点,我希望它显示出来。

为此,我需要设置块 Zblock 的显示,还有它的父块的显示* 块,以及它的父块,一直到块 B....

我不想 "hard" 编写所有可能级别的代码,因为我可以有 2、4 或 10 个级别。所以我想找到一种自动完成的方法。

我稍微简化了上面的示例,因为我必须每 2 "generations" 设置一次 display=block(参见我的代码中的 parentNode.parentNode

到目前为止,这是我的代码(在兔子洞里有 2 级!)而不是自动化:

function indexLink(link_to_anchor) {
    var x = document.getElementById(link_to_anchor);
    if (x.parentNode.parentNode.getAttribute("class") == "divcodebox") {
        if (x.parentNode.parentNode.parentNode.parentNode.getAttribute("class") == "divcodebox") {
            x.parentNode.parentNode.parentNode.parentNode.style.display = "block";
        }
        x.parentNode.parentNode.style.display = "block";
    }
    x.style.display = "block";
}

递归使用 indexLink() :

function indexLink(link_to_anchor) {
    var x = document.getElementById(link_to_anchor);
    x.style.display = "block";
    if (x.parentNode.parentNode.getAttribute("class") == "divcodebox") {
        x.parentNode.parentNode.style.display = "block";
        indexLink(x)
    }
}

一个简单的 for 循环怎么样?

    var x = document.getElementById(link_to_anchor);
    for (parent = x.parentNode; parent; parent = parent.parentNode) {
      // do whatever
    }

你当然可以保留一个计数器来检查你已经走过了多少步等。document 级别的 .parentNode 引用将是 null,这样就结束了迭代。 (你也可以早点跳出循环。)

function recursiveApply(from, to, fn) {
    let current = from;

    while(current !== to) {
        fn(current);
        current = current.parentElement;
    }
}

然后像这样使用它:

var a = document.getElementById("1");
var b = document.getElementById("2");

recursiveApply(a, b, function(element) {
    // do stuff with the element
    console.log(element)
});

这只是为了展示您的递归函数应该如何基于您的代码而非完成的示例。

;function indexLink(element){
    //REM: Change the parameter to the actual element instead of its id
    //var x = document.getElementById(link_to_anchor);

    //REM: Check if the element exists and the style does not equal block
    //REM: If the styles are set by class you need to change this to computed style
    if(element && element.style.display !== 'block'){
        //REM: Set the display to block
        element.style.display = 'block';

        //REM: Repeating the same logic for the parentNode
        indexLink(element.parentNode)
    }
};