JavaScript - 将元素节点附加到文本节点父节点
JavaScript - Appending element node to text node parent
我正在尝试向文本节点的父节点添加一个新元素,但是我的所有尝试都没有奏效。我想从文本节点中提取一些文本并将其转换为 <a>
标记,然后将该节点和剩余文本添加到文本节点的父节点。
以下是我在这个问题上的最新尝试:
var regex = new RegExp(/(^|\s|:|-)((?:0x)[0-9a-fA-F]{40})(?:\s|$)/gi, "gi");
var replace = '<a href="/"></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>
我的问题是,每当我尝试向文本节点的父级添加元素时,它都不会发生。我知道您不能将元素添加到文本节点,但我没有这样做,我是在向文本节点的父节点添加新元素。
我做错了什么?
根本原因好像是你循环了live HTMLCollections(document.getElementsByTagName()
) and collection of nodes (objNode.childNodes
),同时修改了父节点。
因此,当您遍历集合时,随着新元素进入集合或被删除,您的循环变得不可靠。
解决方法是用单个替换节点替换当前节点,但您必须注意不要引入会被 arrWhitelistedTags
!
检测到的标签
将十六进制值替换为 link 时出现同样的问题。为了不移动您正在遍历的集合,您应该用 单个 替换节点替换文本节点。
var regex = new RegExp(/(^|\s|:|-)((?:0x)[0-9a-fA-F]{40})(?:\s|$)/gi, "gi");
var replace = '<a href="/"></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>
我正在尝试向文本节点的父节点添加一个新元素,但是我的所有尝试都没有奏效。我想从文本节点中提取一些文本并将其转换为 <a>
标记,然后将该节点和剩余文本添加到文本节点的父节点。
以下是我在这个问题上的最新尝试:
var regex = new RegExp(/(^|\s|:|-)((?:0x)[0-9a-fA-F]{40})(?:\s|$)/gi, "gi");
var replace = '<a href="/"></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>
我的问题是,每当我尝试向文本节点的父级添加元素时,它都不会发生。我知道您不能将元素添加到文本节点,但我没有这样做,我是在向文本节点的父节点添加新元素。
我做错了什么?
根本原因好像是你循环了live HTMLCollections(document.getElementsByTagName()
) and collection of nodes (objNode.childNodes
),同时修改了父节点。
因此,当您遍历集合时,随着新元素进入集合或被删除,您的循环变得不可靠。
解决方法是用单个替换节点替换当前节点,但您必须注意不要引入会被 arrWhitelistedTags
!
将十六进制值替换为 link 时出现同样的问题。为了不移动您正在遍历的集合,您应该用 单个 替换节点替换文本节点。
var regex = new RegExp(/(^|\s|:|-)((?:0x)[0-9a-fA-F]{40})(?:\s|$)/gi, "gi");
var replace = '<a href="/"></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>