2017-10-27 4 views
0

テキストノードの親に新しい要素を追加しようとしていますが、すべての試みが機能していません。テキストノードからテキストを抽出して<a>タグに変換し、そのノードと残りのテキストをテキストノードの親に追加します。JavaScript - 要素ノードをテキストノードの親に追加する

以下は、この問題で私の最新の試みです:

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();
<span>text about things 0xa74476443119A942dE498590Fe1f2454d7D4aC0d and some more text over here <a href="#">A link somewhere</a> more text here 0xa74476443119A942dE498590Fe1f2454d7D4aC0d</span>

私の問題は、私はテキストノードの親に要素を追加しようとするたびに、それが起こらないということです。テキストノードに要素を追加することはできませんが、私はそれをやっていません。私はtextNodeの親ノードに新しい要素を追加しています。

私は間違っていますか?

答えて

1

根本的な原因は、あなたループを通るライブ HTMLCollections(document.getElementsByTagName())とノード(objNode.childNodes)の収集、および、同時に親ノードを変更しているという事実のようです。

したがって、コレクション内を歩いている間に、新しい要素がコレクションに入ったり削除されたりすると、ループは信頼できなくなります。

回避策は、現在のノードを1つの置換ノードで置き換えることですが、arrWhitelistedTagsによって検出されるタグを導入しないように注意する必要があります。

リンクで16進値を置き換えると同じ問題が発生します。歩いているコレクションを移動しないようにするには、テキストノードを単一ノードの交換ノードに置き換える必要があります。

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();
<span>text about things 0xa74476443119A942dE498590Fe1f2454d7D4aC0d and some more text over here <a href="#">A link somewhere</a> more text here 0xa74476443119A942dE498590Fe1f2454d7D4aC0d</span>

+0

OKああ、私は子リストに要素を挿入し、その後、物事がでている順番をめちゃくちゃにしています。ありがとうございます。 –

関連する問題