JS 循环的appendChild 产生奇怪的行为

发布于 2024-11-18 01:40:10 字数 2069 浏览 1 评论 0原文

我有这个函数:

//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.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]);
    }
}

这意味着获取作为全局变量提供的类/ID 数组,并生成一个包含所有请求元素的数组。然后应该通过使用appendchild循环生成的数组来将子节点(在本例中为链接)附加到兄弟节点。

然而,最终的循环并没有导致页面上有一堆额外的链接,而是附加子级,然后立即将其删除,通过循环进行工作,直到允许保留其生成的链接的最终元素。

我找不到这种行为的解释或任何有类似问题的人。

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.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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

知足的幸福 2024-11-25 01:40:10

您不能将一个元素附加到 DOM 中的多个位置。每次循环时,您都需要附加 finalRender(及其后代)的单独副本

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

请记住,不同的浏览器处理具有绑定事件的克隆元素的方式不同:有些会结束克隆具有与原始绑定相同的事件,而其他克隆则不会。

而且,这些循环非常简洁。中间的两个可以完全替换为:

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

或者,更好的是,直接在第一个循环中构造 elementList ,这样您就不会创建一堆稍后实际上不会使用的数组,或者甚至最好,只需在第一个循环中进行附加即可。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文