【问题标题】:Appending HTML elements on a loop在循环中附加 HTML 元素
【发布时间】:2019-07-16 14:14:23
【问题描述】:

给定一个像这样的 JSON 结构:

[
"Hi, ",
  {
    "tag": "a",
    "attr": {
      "href": "https://example.com",
      "target": "_blank"
    },
    "body": [
      "click ",
      {
        "tag": "strong",
        "body": [
          "here "
        ]
      }
    ]
  },
  "to get ",
  {
    "tag": "em",
    "body": [
      "amazing "
    ]
  },
  "offers."
]  

我正在尝试对其进行迭代以将值转换为 HTML 标记。使用上面的 JSON,我希望构建这个:

<span>Hi, </span><a href="https://google.com" target="_blank">click <strong>here</strong></a>to get <em>amazing </em><span>offers.</span>

所以我将这个 JSON 传递给一个递归函数,如下所示:

 stringHtmlText(content) {
   let result = content.map(tranche => {
        if (typeof tranche === "object") {
            let attrs = [];
            for (let attr in tranche.attr) {
                if (tranche.attr.hasOwnProperty(attr)) {
                    let thisAttr = {};
                    thisAttr[attr] = tranche.attr[attr];
                    attrs.push(thisAttr);
                }
            }

            return tranche.body.map(entry => {
                if (typeof entry === "object") {
                    let childNode = this.stringHtmlText([entry]);
                    if(Array.isArray(childNode)) {
                        childNode = childNode[0];
                    }
                    let parentNode = this.buildElement(tranche.tag, attrs, '');
//THIS IS THE OFFENDING LINE
                    parentNode.appendChild(childNode);
                    return parentNode;
                } else {
                    return this.buildElement(tranche.tag, attrs, entry);

                }
            })[0];

        } else {
            return this.buildElement('span', [], tranche);
        }

    });
    return result;
}

其中 buildElement 是创建节点、设置属性和附加任何文本节点的便捷方法:

 buildElement(tag, attributes, value = '') {
        let node = document.createElement(tag);
        if (value) {
            let text = document.createTextNode(value);
            node.appendChild(text);
        }
        if (attributes.length === 0) {
            return node;
        }
        return this.setAttributes(node, attributes);
    }

我遇到的问题是,即使在调试时我看到“强”节点被传递给 parentNode.appendChild(childNode),当返回值时,父节点“a”标签没有子“强”,给我这样的结果:

<span>Hi, </span><a href="https://google.com" target="_blank">click </a><span>to get </span><em>amazing </em><span>offers.</span>

这显然是缺少“a”标签内的“strong”标签。为什么节点没有附加到父节点?

【问题讨论】:

    标签: javascript recursion dom


    【解决方案1】:

    似乎问题在于,在正文中同时存在纯文本和附加节点的情况下,第二个映射函数实际上生成了两个节点。

    由于第一次迭代只包含文本节点,因此获得第二次完整迭代的方法是将映射的结果传递给一个变量,然后返回数组中的最后一个索引,如下所示:

     stringHtmlText(content) {
        {
            return content.map(tranche => {
                if (typeof tranche === "object") {
                    let attrs = [];
                    for (let attr in tranche.attr) {
                        if (tranche.attr.hasOwnProperty(attr)) {
                            let thisAttr = {};
                            thisAttr[attr] = tranche.attr[attr];
                            attrs.push(thisAttr);
                        }
                    }
                    let parentNode;
    //Assign to variable
                    let trancher = tranche.body.map(entry => {
                        if (typeof entry === "object") {
                            let childNode = this.stringHtmlText([entry]);
                            if (Array.isArray(childNode)) {
                                childNode = childNode[0];
                            }
                            parentNode.appendChild(childNode);
                            return parentNode;
                        } else {
                            parentNode = this.buildElement(tranche.tag, attrs, entry);
                            return parentNode;
                        }
                    });
    // Return only the last, complete node
    
                    return trancher[(trancher.length - 1)]
    
                } else {
                    return this.buildElement('span', [], tranche);
                }
    
            });
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 2021-08-15
      • 1970-01-01
      • 2014-07-10
      • 2019-05-06
      • 1970-01-01
      • 2013-12-17
      相关资源
      最近更新 更多