用铬扩展名替换链接 [英] Replace text with link with chrome extension

查看:78
本文介绍了用铬扩展名替换链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用链接替换网页上的文字。当我尝试这个时,它只是用标签替换文本而不是链接。例如,此代码将用以下内容替换river:

 < a href =http://www.cnn.com > ASDF< / A> 

这就是我到目前为止:

 函数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> 元素。

下面的代码应该做你想做的事情。它用< span> 替换 textNode ,其中包含新的文本节点和创建的 < a> 元素。它仅在需要插入一个或多个< a> 元素时才进行替换。



  function handleTextNode(textNode){if(textNode.nodeName!=='#text'|| textNode.parentNode.nodeName ==='SCRIPT'|| textNode.parentNode.nodeName ==='STYLE'){//除文本节点之外不做任何操作,它们不是< script>或< style> ;.返回; } let origText = textNode.textContent; let newHtml = origText.replace(/ \briver\b / g,'< a href =http://www.cnn.com> asdf< / a>'); //如果我们在文本中实际进行了替换,则只更改DOM。 //比较字符串,因为它应该比第二次RegExp操作更快,并且/ /让我们只在一个地方使用RegExp进行可维护性。 if(newHtml!== origText){let newSpan = document.createElement('span'); newSpan.innerHTML = newHtml; textNode.parentNode.replaceChild(newSpan,textNode); }} //测试:漫游< body>的DOM处理所有非空文本节点function processDocument(){//创建TreeWalker let treeWalker = document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT,{acceptNode:function(node){if(node.textContent.length === 0 ){//或者,可以在这里过滤掉< script>和< style>文本节点。 //在修改DOM之前制作文本节点的列表。一旦DOM被修改,TreeWalker就会失效(即TreeWalker将在第一次修改后停止//遍历DOM)。让nodeList = []; while(treeWalker.nextNode()){nodeList.push(treeWalker.currentNode); } //迭代所有文本节点,在列表中的每个节点上调用handleTextNode。 ();} document.getElementById('clickTo')。addEventListener('click',processDocument,false);  

< input type =buttonid =clickTovalue =Click to process/><<<< ; div id =testDiv>这段文字应该改为link→&river< - 。< / div>

div>



TreeWalker代码取自我的答案在这里


I am trying to replace text on a webpage with links. When I try this it just replaces the text with the tag and 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;
}

解决方案

If all you wanted to do was change the text to other plain text, then you could change the contents of the text nodes directly. However, you are wanting to add an <a> element. For each <a> element you want to add, you are effectively wanting to add a child element. Text nodes can not have children. Thus, to do this you have to actually replace the text node with a more complicated structure. In doing so, you will want to make as little impact on the DOM as possible, in order to not disturb other scripts which rely on the current structure of the DOM. The simplest way to make little impact is to replace the text node with a <span> which contains the new text nodes (the text will split around the new <a>) and any new <a> elements.

The code below should do what you desire. It replaces the textNode with a <span> containing the new text nodes and the created <a> elements. It only makes the replacement when one or more <a> elements need to be inserted.

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.

这篇关于用铬扩展名替换链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆