Добавление элементов HTML в цикл - PullRequest
0 голосов
/ 22 февраля 2019

Учитывая такую ​​структуру 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),когда возвращено значение, у тега parentNode «a» нет дочернего «strong», что дает мне следующий результат:

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

В котором явно отсутствует тег «strong» внутри тега «a».Почему узел не добавляется к родителю?

1 Ответ

0 голосов
/ 22 февраля 2019

Похоже, проблема заключалась в том, что вторая функция отображения фактически генерировала два узла в тех случаях, когда в теле имелся как простой текст, так и дополнительный узел.

Поскольку первая итерация содержит только текстовый узелспособ получить вторую полную итерацию состоял в том, чтобы передать результаты сопоставления переменной и затем вернуть последний индекс в массиве, например:

 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);
            }

        });
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...