我正在尝试用链接替换网页上的文本。当我尝试这样做时,它只是用标签替换文本,而不是链接。例如,此代码将用以下内容替换“河流”:
<a href="http://www.cnn.com">asdf</a>
这是我到目前为止所拥有的:
function handleText(textNode)
{
var v = textNode.nodeValue;
v = v.replace(/\briver\b/g, '<a href="http://www.cnn.com">asdf</a>');
textNode.nodeValue = v;
}
如果您只想将文本更改为其他纯文本,那么您可以直接更改文本节点的内容。但是,您想要添加一个<a>
元素。对于每个<a>
您想要添加的元素,实际上就是想添加一个子元素。文本节点不能有子节点。因此,要做到这一点,您实际上必须用更复杂的结构替换文本节点。这样做时,您将希望对 DOM 产生尽可能小的影响,以免干扰依赖于 DOM 当前结构的其他脚本。影响不大的最简单方法是将文本节点替换为<span>
其中包含新的文本节点(文本将围绕新的文本节点分割)<a>
)和任何新的<a>
元素。
下面的代码应该可以满足您的要求。它取代了textNode
with a <span>
包含新的文本节点和创建的<a>
元素。仅当一个或多个时才进行替换<a>
需要插入元素。
function handleTextNode(textNode) {
if(textNode.nodeName !== '#text'
|| textNode.parentNode.nodeName === 'SCRIPT'
|| textNode.parentNode.nodeName === 'STYLE'
) {
//Don't do anything except on text nodes, which are not children
// of <script> or <style>.
return;
}
let origText = textNode.textContent;
let newHtml=origText.replace(/\briver\b/g,'<a href="http://www.cnn.com">asdf</a>');
//Only change the DOM if we actually made a replacement in the text.
//Compare the strings, as it should be faster than a second RegExp operation and
// lets us use the RegExp in only one place for maintainability.
if( newHtml !== origText) {
let newSpan = document.createElement('span');
newSpan.innerHTML = newHtml;
textNode.parentNode.replaceChild(newSpan,textNode);
}
}
//Testing: Walk the DOM of the <body> handling all non-empty text nodes
function processDocument() {
//Create the TreeWalker
let treeWalker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT,{
acceptNode: function(node) {
if(node.textContent.length === 0) {
//Alternately, could filter out the <script> and <style> text nodes here.
return NodeFilter.FILTER_SKIP; //Skip empty text nodes
} //else
return NodeFilter.FILTER_ACCEPT;
}
}, false );
//Make a list of the text nodes prior to modifying the DOM. Once the DOM is
// modified the TreeWalker will become invalid (i.e. the TreeWalker will stop
// traversing the DOM after the first modification).
let nodeList=[];
while(treeWalker.nextNode()){
nodeList.push(treeWalker.currentNode);
}
//Iterate over all text nodes, calling handleTextNode on each node in the list.
nodeList.forEach(function(el){
handleTextNode(el);
});
}
document.getElementById('clickTo').addEventListener('click',processDocument,false);
<input type="button" id="clickTo" value="Click to process"/>
<div id="testDiv">This text should change to a link -->river<--.</div>
The TreeWalker code was taken from my answer here https://stackoverflow.com/a/37566073/3773011.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)