用带有chrome扩展名的链接替换文本

时间:2016-10-27 04:30:59

标签: javascript google-chrome-extension

我正在尝试用链接替换网页上的文字。当我尝试这个时,它只是用标签而不是链接替换文本。例如,此代码将用“

”替换“river”
<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;
}

1 个答案:

答案 0 :(得分:1)

如果您只想将文本更改为其他纯文本,则可以直接更改文本节点的内容。但是,您想要添加<a>元素。对于要添加的每个<a>元素,您实际上想要添加子元素。文本节点不能有子节点。因此,要做到这一点,您必须用更复杂的结构替换文本节点。在这样做时,您将希望尽可能减少对DOM的影响,以免干扰依赖于DOM的当前结构的其他脚本。影响不大的最简单方法是将文本节点替换为<span>,其中包含新文本节点(文本将围绕新<a>分开)和任何新的<a>元素。

下面的代码应该按照您的意愿行事。它将textNode替换为包含新文本节点和创建的<span>元素的<a>。只有在需要插入一个或多个<a>元素时才会进行替换。

&#13;
&#13;
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);
&#13;
<input type="button" id="clickTo" value="Click to process"/>
<div id="testDiv">This text should change to a link -->river<--.</div>
&#13;
&#13;
&#13;

TreeWalker代码取自my answer here