views:

553

answers:

6

What I want to do is replace all instances of 'old' in a webpage with 'new' in a JS bookmarklet or a greasemonkey script. How can I do this? I suppose jQuery or other frameworks are okay, as there're hacks to include them in both bookmarklets as well as greasemonkey scripts.

A: 

Hey you could try this, problem is it searches the entire body so even attributes and such get changed.

javascript:document.body.innerHTML=document.body.innerHTML.replace( /old/g, "new" );
Kane Wallmann
+4  A: 

A function that is clobber-proof. That mean's this won't touch any tags or attributes, only text.

function htmlreplace(a, b, element) {    
    if (!element) element = document.body;    
    var nodes = element.childNodes;
    for (var n=0; n<nodes.length; n++) {
        if (nodes[n].nodeType == Node.TEXT_NODE) {
            var r = new RegExp(a, 'gi');
            nodes[n].textContent = nodes[n].textContent.replace(r, b);
        } else {
            htmlreplace(a, b, nodes[n]);
        }
    }
}

htmlreplace('a', 'r');

Bookmarklet version:

javascript:function htmlreplace(a,b,element){if(!element)element=document.body;var nodes=element.childNodes;for(var n=0;n<nodes.length;n++){if(nodes[n].nodeType==Node.TEXT_NODE){nodes[n].textContent=nodes[n].textContent.replace(new RegExp(a,'gi'),b);}else{htmlreplace(a,b,nodes[n]);}}}htmlreplace('old','new');
sixthgear
Edited my answer to not require jQuery
sixthgear
A: 

A simple line that works along jQuery:

`javascript:var a = function(){$("body").html($("body").html().replace(/old/g,'new'));return;}; a();`

Without jQuery:

`javascript:function a (){document.body.innerHTML=document.body.innerHTML.replace(/old/g, "new" );return;}; a();`

The function returning nothing is very important, so the browser is not redirected anywhere after executing the bookmarklet.

Rodrigo Gama
+1  A: 

If you replace the innerHtml then you will destroy any dom events you have on the page. Try traversing the document to replace text:

function newTheOlds(node) {
    node = node || document.body;
    if(node.nodeType == 3) {
        // Text node
        node.nodeValue = node.nodeValue.split('old').join('new');
    } else {
        var nodes = node.childNodes;
        if(nodes) {
            var i = nodes.length;
            while(i--) newTheOlds(nodes[i]);
        }
    }
}

newTheOlds();

The split/join is faster than doing "replace" if you do not need pattern matching. If you need pattern matching then use "replace" and a regex:

node.nodeValue = node.nodeValue.replace(/(?:dog|cat)(s?)/, 'buffalo$1');

As a bookmarklet:

javascript:function newTheOlds(node){node=node||document.body;if(node.nodeType==3){node.nodeValue=node.nodeValue.split('old').join('new');}else{var nodes=node.childNodes;if(nodes){var i=nodes.length;while(i--)newTheOlds(nodes[i]);}}}newTheOlds();
Prestaul
A: 

Yet another recursive approach:

function replaceText(oldText, newText, node){ 
  node = node || document.body; 

  var childs = node.childNodes, i = 0;

  while(node = childs[i]){ 
    if (node.nodeType == Node.TEXT_NODE){ 
      node.textContent = node.textContent.replace(oldText, newText); 
    } else { 
      replaceText(oldText, newText, node); 
    } 
    i++; 
  } 
}

Minified bookmarklet:

javascript:function replaceText(ot,nt,n){n=n||document.body;var cs=n.childNodes,i=0;while(n=cs[i]){if(n.nodeType==Node.TEXT_NODE){n.textContent=n.textContent.replace(ot,nt);}else{replaceText(ot,nt,n);};i++;}};replaceText('old','new');
CMS
A: 

Okay, I'm just consolidating some of the great stuff that people are putting up in one answer.

Here is sixthgear's jQuery code, but made portable (I source jQuery from the big G) and minified into a bookmarklet:

javascript:var scrEl=document.createElement('script');scrEl.setAttribute('language','javascript');scrEl.setAttribute('type','text/javascript');scrEl.setAttribute('src','http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js');function htmlreplace(a,b,element){if(!element)element=document.body;var nodes=$(element).contents().each(function(){if(this.nodeType==Node.TEXT_NODE){var r=new RegExp(a,'gi');this.textContent=this.textContent.replace(r,b);}else{htmlreplace(a,b,this);}});}htmlreplace('old','new');

NOTE that 'old' can be either a 'string literal', or a 'reg[Ee]x'.

Actually, now that I think about it, sixthgear's is the best answer, especially with my enhancements. I can't find anything that the other answers add over it, using jQuery achieves incredible X-browser compatibility. Plus, I'm just fucking lazy. community wiki, Enjoy!

Fooby