Replace text with chrome extension link

I am trying to replace text on a webpage with links. When I try to do this, it simply replaces the text with a tag, not a link. For example, this code will replace "river" with:

<a href="http://www.cnn.com">asdf</a> 

This is what I have so far:

 function handleText(textNode) { var v = textNode.nodeValue; v = v.replace(/\briver\b/g, '<a href="http://www.cnn.com">asdf</a>'); textNode.nodeValue = v; } 
+1
source share
1 answer

If all you wanted to do was change the text to another plain text, you can directly change the contents of the text nodes. However, you want to add the <a> element. For each <a> element you want to add, you really want to add a child element. Text nodes cannot have children. Thus, for this you need to replace the text node with a more complex structure. In doing so, you will want to influence the DOM as little as possible so as not to break other scripts that rely on the current DOM structure. The easiest way to make a small impact is to replace the text node with <span> , which contains the new text nodes (the text will be divided around the new <a> ) and any new <a> elements.

The code below should do what you want. It replaces textNode with <span> , which contains new text nodes and created <a> elements. It replaces only one or more <a> elements.

 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 (ie 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> 

TreeWalker code was taken from my answer here .

+1
source

Source: https://habr.com/ru/post/1259671/


All Articles