2012-01-21 75 views
1

我在HTML页面上有一些文本。Javascript Bookmarklet用链接替换文本

实施例后
aaa bbb ccc ddd 

: 需要一个书签(无jQuery的),将使用正则表达式查找的文本的片段,然后用与该文本作为

实施例之前的参数的链路替换它

aaa <a href="http:www.whatever.com?bbb">bbb</a> ccc ddd 

假设我们正在寻找 “BBB”

回答

7

该解决方案将抓取DOM搜索文档元素内的文本节点,跳过您想要的任何元素。例如,您可能要跳过<a>标记以及<脚本>标记和其他标记。这样,您不会替换元素节点或基本页面功能。

(function(){ 
    // don't replace text within these tags 
    var skipTags = { 'a': 1, 'style': 1, 'script': 1, 'iframe': 1 }; 

    // find text nodes to apply replFn to 
    var findKW = function (el, term, replFn) { 
     var child, tag; 

     for (var i = el.childNodes.length - 1; i >= 0; i--) { 
      child = el.childNodes[i]; 
      if (child.nodeType == 1) { // ELEMENT_NODE 
       tag = child.nodeName.toLowerCase(); 
       if (!(tag in skipTags)) { 
        findKW(child, term, replFn); 
       } 
      } else if (child.nodeType == 3) { // TEXT_NODE 
       replaceKW(child, term, replFn); 
      } 
     } 
    }; 

    // replace terms in text according to replFn 
    var replaceKW = function (text, term, replFn) { 
     var match, 
      matches = []; 

     while (match = term.exec(text.data)) { 
      matches.push(match); 
     } 
     for (var i = matches.length - 1; i >= 0; i--) { 
      match = matches[i]; 

      // cut out the text node to replace 
      text.splitText(match.index); 
      text.nextSibling.splitText(match[1].length); 
      text.parentNode.replaceChild(replFn(match[1]), text.nextSibling); 
     } 
    }; 

    var replTerm = prompt('Please enter term to replace'); 

    findKW(
     document.body, 

     // using \\b to only replace when the term is the whole word 
     // e.g. if term is "bbb" then "aabbbccc" will not match 
     new RegExp('\\b(' + replTerm + ')\\b', 'g'), 

     // your replacement function, change URL accordingly 
     function (match) { 
      var link = document.createElement('a'); 
      link.href = 'http://google.com/#q=' + match; 
      link.target = '_blank'; 
      link.innerHTML = match; 
      return link; 
     } 
    ); 
}());   

这在书签的形式最小化:

javascript:(function(){var a={a:1,style:1,script:1,iframe:1};var b=function(d,e,f){var g,h;for(var i=d.childNodes.length-1;i>=0;i--){g=d.childNodes[i];if(g.nodeType==1){h=g.nodeName.toLowerCase();if(!(h in a)){b(g,e,f)}}else if(g.nodeType==3){c(g,e,f)}}};var c=function(a,b,c){var d,e=[];while(d=b.exec(a.data)){e.push(d)}for(var f=e.length-1;f>=0;f--){d=e[f];a.splitText(d.index);a.nextSibling.splitText(d[1].length);a.parentNode.replaceChild(c(d[1]),a.nextSibling)}};var d=prompt("Please enter term to replace");b(document.body,new RegExp("\\b("+d+")\\b","g"),function(a){var b=document.createElement("a");b.href="http://google.com/#q="+a;b.target="_blank";b.innerHTML=a;return b})})() 

复制成书签,并尝试一下任何网页上!注意:搜索区分大小写,但可以将“i”标志添加到RegExp以防止出现这种情况。

+0

似乎无法与parent.document一起使用。我在iframe中试过这段代码,结果是将HTML链接写成文本而不是可点击的链接。请你有任何想法在Iframe中使用这个脚本来修改父文档? – Valky

0

最简单的正则表达式:

document.body.innerHTML = document.body.innerHTML.replace(/bbb/ , '<a href="http://Google.com">bbb</a>'); 

更好:

document.body.innerHTML = document.body.innerHTML.replace(/(bbb)/ , '<a href="http://Google.com">$1</a>'); 

最佳:

var srch = "bbb"; 
var rg = new RegExp("("+srch+")"); 
document.body.innerHTML = document.body.innerHTML.replace(rg , '<a href="http://Google.com">$1</a>'); 

在正则表达式中的括号表示一个匹配组。第二个参数中的“$ 1”是第一个匹配的组。

+0

如果您的搜索字词是'div'或'img'或'href'或'script',您可能会遇到此实现方面的问题... – mVChr