开发者

JS Looped appendChild producing strange behaviour

I have this function:

//add links to called classes
function addLinks () {
    var classElements = [];
    var idElements = [];
    var finalRender;
    var expand = document.createTextNode("+");
    var contract = document.createTextNode("-");
    var elementsList = [];
    var count = 0;

    //create the dom nodes
    renderPElements = document开发者_如何学Python.createElement ("p");

        renderAElements = document.createElement ("a");
        renderAElements.setAttribute("href", "#");
        renderAElements.setAttribute("class", "expander");
        renderAElements.appendChild(expand);
        finalRender = renderPElements.appendChild(renderAElements);


    //get arrays of elements with class or id set to provided string
    for (var i = 0; i< show_hide_class_selectors.length; i++) {
        classElements[i] = document.getElementsByClassName(show_hide_class_selectors[i]);

        //if prevents null value appearing in array and freezing script
        if (document.getElementById(show_hide_class_selectors[i])) {
        idElements[i] = document.getElementById (show_hide_class_selectors[i]);
        }
    }

    //loop though selected id's / classes and generate a single array of selected elements
    for (var i = 0; i< idElements.length; i++) {
        elementsList[count] = idElements[i];
        count = count +1;
    }

    //must loop twice as variable is 2 dimensional i=class name y=elements of that class
    for (var i = 0; i< classElements.length; i++) {
        for (var y = 0; y< classElements[i].length; y++) {
        elementsList[count] = classElements[i][y];
        count = count +1;
        }
    }

    //render
    for (var i = 0; i< elementsList.length; i++) {
        alert ("render");
        elementsList[i].parentNode.firstChild.appendChild(finalRender);

        alert (elementsList[i]);
    }
}

Which is meant to take an array of classes / ids provided as a global variables and produce an array that contains all the requested elements. It is then supposed to append childnodes (links in this case) to sibling nodes by looping though the generated array using appendchild.

However instead of resulting in a page that has a bunch of extra links on it, the final loop instead appends the child and then immediately removes it, working its way though the loop until the final element which is permitted to retain it's generated link.

I can find no explaination for this behaviour or anyone with a similiar problem.


You can't append an element to more than one spot in the DOM. You need to append a separate copy of finalRender (and descendants) each time through the loop:

elementsList[i].parentNode.firstChild.appendChild(finalRender.cloneNode(true));

Keep in mind that different browsers handle cloning elements with bound events differently: some will end up with the clone having the same events bound as the original, others will not.

Also, those loops are screaming for brevity. The middle two can be completely replaced with just:

elementList = idElements;
for (var i=0; i<classElements.length; ++i)
    elementList = elementList.concat(classElements[i]);

Or, even better, just construct elementList directly within the first loop, so you don't make a bunch of arrays that you don't actually use later, or even best, just do the append right in the first loop.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜