JavaScript - 将元素节点附加到文本节点父节点

时间:2017-10-27 10:51:59

标签: javascript append element textnode

我正在尝试将新元素添加到文本节点的父节点,但是我的所有尝试都无效。我想从文本节点中提取一些文本并将其转换为<a>标记,然后将该节点和剩余文本添加到文本节点的父节点。

以下是我对此问题的最新尝试:

&#13;
&#13;
var regex = new RegExp(/(^|\s|:|-)((?:0x)[0-9a-fA-F]{40})(?:\s|$)/gi, "gi");
var replace = '$1<a href="/$2">$2</a>';

function convertHexToLink()
{
    var arrWhitelistedTags = ["code", "span", "p", "td", "li", "em", "i", "b", "strong", "small"];

    //Get the whitelisted nodes
    for(var i=0; i<arrWhitelistedTags.length; i++) {
        var objNodes = document.getElementsByTagName(arrWhitelistedTags[i]);
        //Loop through the whitelisted content
        for(var x=0; x<objNodes.length; x++) {
            convertHex(objNodes[x], regex, replace);
        }
    }
}

function convertHex(objNode, replaceRegex, replacePattern)
{
    // Some nodes have non-textNode children
    // we need to ensure regex is applied only to text otherwise we will mess the html up
    for(var i=0; i < objNode.childNodes.length; i++){
        if(objNode.childNodes[i].nodeType == 3){ // nodeType 3 = a text node

            var child = objNode.childNodes[i];
            var strContent = child.textContent;

            var element = document.createElement('div');
            element.innerHTML = strContent.replace(replaceRegex, replacePattern);
            
            console.log(element.outerHTML);
            console.log(element.childNodes.length);

            for(var x=0; x < element.childNodes.length; x++){
                console.log("Element Child Node :");
                console.log(element.childNodes[x].innerHTML);
                child.parentNode.insertBefore(element.childNodes[x], child);
            }
            child.parentNode.removeChild(child);
        }
    }
}

convertHexToLink();
&#13;
<span>text about things 0xa74476443119A942dE498590Fe1f2454d7D4aC0d and some more text over here <a href="#">A link somewhere</a> more text here 0xa74476443119A942dE498590Fe1f2454d7D4aC0d</span>
&#13;
&#13;
&#13;

我的问题是,每当我尝试将一个元素添加到文本节点的父节点时,它就不会发生。我知道您无法在文本节点中添加元素,但我没有这样做我在textNode的父节点上添加了一个新元素。

我做错了什么?

1 个答案:

答案 0 :(得分:1)

根本原因似乎是您循环实时 HTMLCollections(document.getElementsByTagName())和节点集合(objNode.childNodes),并修改了父节点同一时间。

因此,当你走过集合时,你的循环变得不可靠,因为新元素会进入集合或被删除。

解决方法是通过单个替换节点替换当前节点,但您必须注意不要引入将由arrWhitelistedTags检测到的标记!

通过链接替换十六进制值时会出现同样的问题。为了不移动您正在浏览的集合,您应该用单个替换节点替换文本节点。

&#13;
&#13;
var regex = new RegExp(/(^|\s|:|-)((?:0x)[0-9a-fA-F]{40})(?:\s|$)/gi, "gi");
var replace = '$1<a href="/$2">$2</a>';

function convertHexToLink() {
  var arrWhitelistedTags = ["code", "span", "p", "td", "li", "em", "i", "b", "strong", "small"];

  //Get the whitelisted nodes
  for (var i = 0; i < arrWhitelistedTags.length; i++) {
    // objNodes is a LIVE HTMLCollection.
    var objNodes = document.getElementsByTagName(arrWhitelistedTags[i]);
    //Loop through the whitelisted content
    for (var x = 0; x < objNodes.length; x++) {
      convertHex(objNodes[x], regex, replace);
    }
  }
}

function convertHex(objNode, replaceRegex, replacePattern) {
  // Some nodes have non-textNode children
  // we need to ensure regex is applied only to text otherwise we will mess the html up
  // objNode.childNodes is a LIVE collection of nodes.
  for (var i = 0; i < objNode.childNodes.length; i++) {
    if (objNode.childNodes[i].nodeType == 3) { // nodeType 3 = a text node
      // Use an HTMLElement that is not in arrWhitelistedTags, in order not to shift objNodes.
      var replacement = document.createElement('sup');

      var child = objNode.childNodes[i];
      var strContent = child.textContent;
      
      replacement.innerHTML = strContent.replace(replaceRegex, replacePattern);
      
      // Replace child (single text node) by replacement (single node), so that objNode.childNodes is not shifted.
      objNode.insertBefore(replacement, child);
      child.parentNode.removeChild(child);
    }
  }
}

convertHexToLink();
&#13;
<span>text about things 0xa74476443119A942dE498590Fe1f2454d7D4aC0d and some more text over here <a href="#">A link somewhere</a> more text here 0xa74476443119A942dE498590Fe1f2454d7D4aC0d</span>
&#13;
&#13;
&#13;

相关问题