简体   繁体   中英

Javascript AppendChild Issue

UPDATED WITH FULL CODE

I'm trying to dynamically add a div onto some other DIV's stored in an array

The array which contains DIV's is named categoryData which contains an attribute with its category name

The shop-row div's (categoryData) is empty at the beginning.

I've got another array which contains the product object stored in an array called storeCategoryData The product object is in the following format,

{CategoryName:categoryname,StoreObject:store_clearfix} // store_clearfix is another div

I'm trying to add the StoreObject into the DIV categoryData. Unfortunately some objects get added and not the others. I can figure out what i'm doing wrong here. Any help would be much appreciated. Thanks!

I tried doing everything possible. Still no luck :(

 var store_list = document.getElementsByClassName("shop-list")[0];


if(data['stores']!=null && data['stores'] !== typeof undefined){

    var numstores = Object.keys(data["stores"]).length;
    var count = 0;

    while (count < numstores) {

        var categories = data["stores"][count].Categories;
        var catcount = categories.length;
        var c=0;

        while(c<catcount){
            var cat = categories[c];

            if (!(storeCategories.indexOf(cat) > -1)) {

                var category_element = document.createElement("li");
                if(count==0 && c==0){
                    category_element.className="active";
                }
                var clickable = document.createElement("a");
                clickable.href = "#";
                clickable.innerText = cat;
                clickable.setAttribute("category-data", cat);
                storeCategories.push(cat);
                category_element.appendChild(clickable);
                category_list.appendChild(category_element);


                var div = document.createElement("div");
                div.className = "shop-row";
                div.setAttribute("category-name", cat);
                categoryData.push(div);
            }

            c++;
        }

        count++;
    }

    count = 0;

    while (count < numstores) {

        var StoreId = data["stores"][count].StoreId;
        var WebsiteUrl = data["stores"][count].WebsiteUrl;
        var LogoUrl = data["stores"][count].LogoUrl;
        var categories = data["stores"][count].Categories;


        var store_clearfix = document.createElement("div");
        store_clearfix.className = "single-products-catagory clearfix";

        var store_atag =  document.createElement("a");
        store_atag.className = "home-shop";
        store_atag.href = WebsiteUrl;

        var store_img = document.createElement("img");
        store_img.className = "shop-icon";
        store_img.src = LogoUrl;
        store_img.alt = StoreId;

        store_atag.appendChild(store_img);
        store_clearfix.appendChild(store_atag);


        c=0;
        catcount = categories.length;
        while(c<catcount){
            var categoryname = categories[c];
            var i = 0;
            var datacount = categoryData.length;
            while(i<datacount){

                var datarow = categoryData[i];
                if(categoryname==datarow.getAttribute("category-name")) {
                    var storeObj = {CategoryName:categoryname,StoreObject:store_clearfix};
                    storeCategoryData.push(storeObj);
                    break;
                }

                i++;

            }

            c++;
        }


        count++;

    }


    categories_tab.appendChild(category_list);

    i=0;
    for (i = 0; i < categoryData.length; i++) {
        var div = categoryData[i];
        console.log(div);

        var name = div.getAttribute("category-name");

        var c;
        for (c = 0; c < storeCategoryData.length; c++) {
            console.log(storeCategoryData[c].CategoryName);
            if(storeCategoryData[c].CategoryName==name){
                console.log(storeCategoryData[c].StoreObject);
                div.appendChild(storeCategoryData[c].StoreObject);
           }

        }

        console.log("Finished "+name );
        console.log(div);
        store_list.appendChild(div);

    }

}

Example variable data defined as follows

{
"status": "success",
"stores": [
    {
        "StoreId": "randomStore",
        "WebsiteUrl": "https://abcd.com",
        "LogoUrl": "https://abcd.come",
        "Categories": [
            "ALL",
            "MENS",
            "WOMENS"
        ]
    },
    {
        "StoreId": "someStoreId",
        "WebsiteUrl": "https://someurl.com",
        "LogoUrl": "https://someLogo.com",
        "Categories": [
            "MENS"
        ]
    }
  ] 
}

在此输入图像描述

The problem you are facing here is caused by the following behavior:

The Node.appendChild() method adds a node to the end of the list of children of a specified parent node. If the given child is a reference to an existing node in the document, appendChild() moves it from its current position to the new position ( MDN: Node.appendChild() )

What this means is that appendChild will remove the node if already present in the DOM, which is what we are seeing here. This can be easily solved by creating a deep clone of the node first using cloneNode , before appending it to the target div, as follows:

var clone = storeCategoryData[c].StoreObject.cloneNode(true);
div.appendChild(clone);

You can also refer to the snippet below for a working example:

 var categories_tab = document.getElementById('category-tab'); var store_list = document.getElementById('store-list'); var storeCategories = []; var storeCategoryData = []; var data = { "status": "success", "stores": [{ "StoreId": "randomStore", "WebsiteUrl": "https://abcd.com", "LogoUrl": "https://abcd.come", "Categories": [ "ALL", "MENS", "WOMENS" ] }, { "StoreId": "someStoreId", "WebsiteUrl": "https://someurl.com", "LogoUrl": "https://someLogo.com", "Categories": [ "MENS" ] } ] }; var categoryData = []; var category_list = document.createElement("ul"); if (data['stores'] != null && data['stores'] !== typeof undefined) { var numstores = Object.keys(data["stores"]).length; var count = 0; while (count < numstores) { var categories = data["stores"][count].Categories; var catcount = categories.length; var c = 0; while (c < catcount) { var cat = categories[c]; if (!(storeCategories.indexOf(cat) > -1)) { var category_element = document.createElement("li"); if (count == 0 && c == 0) { category_element.className = "active"; } var clickable = document.createElement("a"); clickable.href = "#"; clickable.innerText = cat; clickable.setAttribute("category-data", cat); storeCategories.push(cat); category_element.appendChild(clickable); category_list.appendChild(category_element); var div = document.createElement("div"); div.className = "shop-row"; div.setAttribute("category-name", cat); categoryData.push(div); } c++; } count++; } count = 0; while (count < numstores) { var StoreId = data["stores"][count].StoreId; var WebsiteUrl = data["stores"][count].WebsiteUrl; var LogoUrl = data["stores"][count].LogoUrl; var categories = data["stores"][count].Categories; var store_clearfix = document.createElement("div"); store_clearfix.className = "single-products-catagory clearfix"; var store_atag = document.createElement("a"); store_atag.className = "home-shop"; store_atag.href = WebsiteUrl; var p = document.createElement("p"); p.className = "shop-icon"; var t = document.createTextNode(LogoUrl); p.appendChild(t) store_atag.appendChild(p); store_clearfix.appendChild(store_atag); c = 0; catcount = categories.length; while (c < catcount) { var categoryname = categories[c]; var i = 0; var datacount = categoryData.length; while (i < datacount) { var datarow = categoryData[i]; if (categoryname == datarow.getAttribute("category-name")) { var storeObj = { CategoryName: categoryname, StoreObject: store_clearfix }; storeCategoryData.push(storeObj); break; } i++; } c++; } count++; } categories_tab.appendChild(category_list); i = 0; for (i = 0; i < categoryData.length; i++) { var div = categoryData[i]; console.log(div); var name = div.getAttribute("category-name"); var c; for (c = 0; c < storeCategoryData.length; c++) { console.log(storeCategoryData[c].CategoryName); if (storeCategoryData[c].CategoryName == name) { console.log(storeCategoryData[c].StoreObject); var clone = storeCategoryData[c].StoreObject.cloneNode(true); div.appendChild(clone); } } console.log("Finished " + name); console.log(div); store_list.appendChild(div); } } 
 <div id="category-tab" style="min-height: 20px; border: 1px solid; padding: 10px"></div> <div id="store-list" style="min-height: 20px; border: 1px solid green; padding: 10px; margin-top: 30px"></div> 

I can not completely understand what you wrote there but as I can see you want to attach from the JSON string and not Node with appendChild.

var div = categoryData[i];

It should be something like this:

store_list.innerHTML += DIV;

I would not even start a while loop with NULL or empty array categoryData. I would outsource this in a function because if I want to call it dynamically again or first see if it's even available. storeCategoryData is an object and not an array ... etc

I think the reason is that one store element can only be appended to only one category element, even it could belong to multiple categories.

========keep history below:====================

The log looks perfect to me. I can't see the problem.

You wrote the statement:

if(storeCategoryData[c].CategoryName==name)

So, some StoreObject are appended; others are not.

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