JavaScript AppendChild问题

7

完整代码已更新

我正在尝试动态地将一个 div 添加到存储在数组中的某些其他 DIV 上。

包含 DIV 的数组名为 categoryData,其中包含带有其类别名称的属性。

shop-row div(categoryData)一开始是空的。

我有另一个包含产品对象的数组,存储在名为 storeCategoryData 的数组中。产品对象的格式如下:

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

我正在尝试将StoreObject添加到DIV类别数据中。不幸的是,一些对象被添加了,而其他对象没有被添加。我弄不清楚我在这里做错了什么。非常感谢您提供任何帮助。 谢谢! 我尝试了所有可能的方法。仍然没有运气。:(
 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);

    }

}

定义示例变量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"
        ]
    }
  ] 
}

enter image description here


1
你能创建一个 Stack Snippet 或 JSFiddle 吗?没有你的 HTML 代码,很难理解你在问什么。 - Munim Munna
我同意Munim Munna的看法:“不清楚你在问什么”,你的代码是有问题的。当我在JSFiddle上尝试运行它时,会出现多个ReferenceError: {propertyName}未定义的错误。这是JSFiddle的工作示例:https://jsfiddle.net/c3ozfvry/。请提供你期望的结果以及出了什么问题? - Ruben.sar
3个回答

2
您在此面临的问题是由以下行为引起的:
Node.appendChild() 方法将节点添加到指定父节点的子节点列表末尾。如果给定的子节点是文档中现有节点的引用,则 appendChild() 将其从当前位置移动到新位置 (MDN: Node.appendChild())。
这意味着 appendChild 会删除已经存在于 DOM 中的节点,这就是我们在这里看到的情况。可以通过首先使用 cloneNode 创建节点的深层克隆来轻松解决这个问题,然后再将其附加到目标 div 中,如下所示:
var clone = storeCategoryData[c].StoreObject.cloneNode(true);
div.appendChild(clone);

您也可以参考下面的片段以获取一个工作示例:

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>


0

我完全听不懂你在那里写的是什么,但是我可以看出你想要从JSON字符串中附加,而不是使用appendChild来附加节点。

var div = categoryData[i];

应该是这样的:

store_list.innerHTML += DIV;

我甚至不会用NULL或空数组categoryData开始while循环。我会将其外包到一个函数中,因为如果我想要动态调用它,或者首先查看它是否可用。storeCategoryData是一个对象而不是一个数组...等等


categoryData在使用时不是空的,因为数据被添加到数组中,然后再分配到div上。你使用 innerHTML 的解决方案不起作用。 - Elinoter99
我对此有很多要做的事情,但我在你的例子中没有看到所有的东西。也许如果你在这里看一下我的代码:digital.deutsches-museum.de/hitlist/,会对你有所帮助。 - Aleksandar Stajic
我会尝试一下。但请注意,这里的div是一个实际的节点而不是一个字符串,因为appendChild确实起作用。它确实被添加了,但并非每个应该被添加的div都被添加了。在这个例子中,只有两个div被添加了,但如果你看控制台,你会发现应该添加4个div(single-product-category clearfix)。在我添加之前,我将内容打印到了控制台上。 - Elinoter99

-1

我认为原因在于一个存储元素只能被附加到一个类别元素,即使它可能属于多个类别。

========保留历史记录如下:====================

对我来说,日志看起来很完美。我找不到问题。

你写的语句是:

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

所以,一些 `StoreObject` 被追加了,而另一些则没有。

请检查日志中的第183行,日志中第175行的对象未被附加。我就是不明白!为什么呢? - Elinoter99

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接