简体   繁体   中英

forEach function with Extra parameters

Hey so I have a simple function below to walkTheDOM recursively that I want to add some additional features to.

function walkTheDOM(node) {
    if( node.hasChildNodes() ) {
        Array.prototype.forEach.call(node.children, walkTheDOM );
    } 
}

Additional functionality so that I can apply something to each function. Using applyFn to perform an action on each element that the function traverses.

function walkTheDOM(node,applyFn) {
    //do something to each node
    !applyFn || applyFn(node);
    if( node.hasChildNodes() ) {
        forEach.call(node.children, function(childNode){ return walkTheDOM(childNode, applyFn); } );
    } else {
        console.log("Is Leaf:", node);   
    }
}

I would like to clean the code up to be similar to the first code sample, specifically this line:

Array.prototype.forEach.call(node.children, walkTheDOM );

So that it calls the applyFn without having to wrap the walkTheDOM function inside of a function.

Is it possible to do this by idk something like calling forEach.call(child, walkTheDom.call(child, applyFn) ?

Basically, is there anyway to add additional parameters to this function inherently without creating this sort of configuration where an external anonymous function is wrapping my recursive call to add my parameter of applyFn (apply function)?

I'm not concerned with using some sort of jQuery function or other library to complete this task so please don't answer with another way to accomplish the task, such as, "Look into jQuery lib XYZ..." or "jQuery already does this, try jQuery.libXYZ..." etc... I am simply exploring recursion and function calls in JavaScript. I don't care about some other third party that already does this function, this is my question. Thanks.

EDIT Maybe this can be understood better by this code which is more of a classical approach.

function walkTheDOM(node, applyFn) {
    applyFn(node);
    if (node.hasChildNodes()) {
        for (var i = 0; i < node.children.length; i++) {
            walkTheDOM(node.children[i],applyFn);
        }
    }
}

 var forEach = Array.prototype.forEach; var root = document.getElementById("root"); function applyFn(element, index) { // do stuff if (element.hasChildNodes()) { document.getElementsByClassName("result")[0].innerHTML += "<br>Do something with this node: " + element.className; walkTheDOM(element) } else { console.log("Is Leaf:", element); } } function walkTheDOM(node) { if( node.hasChildNodes() ) { forEach.call(node.children, applyFn); } else { console.log("Is Leaf:", node); } } walkTheDOM(root); 
 <div id="root" class="parent1"> <div class="1-child1"> <div class="1-child1-child1"></div> <div class="1-child1-child2"></div> </div> <div class="parent2"> <div class="2-child1"></div> <div class="2-child2"></div> </div> <div class="parent3"></div> </div> <p class="result"></p> 

jsfiddle http://jsfiddle.net/zcwc633k/4/

This avoids duplicate traversing...

function applyMe(node){
    console.log(node)
}
function walkTheDOM(node) {

    if (node.hasChildNodes()) {
        applyMe(node)
        Array.prototype.forEach.call(node.children, walkTheDOM)
    } else {
        applyMe(node)
    }

}

var node = document.getElementById('container');

walkTheDOM(node)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM