开发者

Javascript: Changing color of every "r" in html document

EDIT [how can I] change the color of every R and r in my HTML开发者_开发百科 document with javascript?


I'd use the highlight plugin for jQuery. Then do something like:

$('*').highlight('r'); // Not sure if it's case-insensitive or not

and in CSS:

.highlight { background-color: yellow; }


Doable, but not super easy. There's no CSS way to do it.

Basically, you'll need to use Javascript and iterate through the all nodes. If it's a text node, you can search it for "R" and then replace the R with a <span style="color:red">R</span>

I am obviously simplifying this a bit, it's probably better to just dynamically add a "highlight" class, rather than hard code a style, and have that defined in CSS. Similarly, I'm sure you'll wanna parameterize the search string. Also, this doesn't take into account what the text node is, for instance, I have special handling to skip comments, but you'll probably find there's other things (script nodes?) you also need to skip.

 function updateNodes(node) { 
   if (node.nextSibling)
     updateNodes(node.nextSibling);
   if (node.nodeType ==8) return; //Don't update comments
   if (node.firstChild)
      updateNodes(node.firstChild);
   if (node.nodeValue) { // update me    
       if (node.nodeValue.search(/[Rr]/) > -1){ // does the text node have an R
               var span=document.createElement("span");
               var remainingText = node.nodeValue;
               var newValue='';
               while (remainingText.search(/[Rr]/) > -1){ //Crawl through the node finding each R
                 var rPos = remainingText.search(/[Rr]/);
                 var bit = remainingText.substr(0,rPos);
                 var r = remainingText.substr(rPos,1);
                 remainingText=remainingText.substr(rPos+1);
                 newValue+=bit;
                 newValue+='<span style="color:red">';
                 newValue+=r;
                 newValue+='</span>';
               }
               newValue+=remainingText;
               span.innerHTML=newValue;
               node.parentNode.insertBefore(span,node);
               node.parentNode.removeChild(node);   
            } 
        }
     } 

        function replace(){   updateNodes(document.body); 
}


Yes this is possible with a little Javascript, a smattering of CSS and some regex.

First, you need to define a style which provides the colour you require (in my example below I refer to a CSS class called "new-colour"), and then run some regex over your HTML content which does a search and replace. You are looking to change all 'r' and 'R' characters into something like this (as an example):

<span class="new-colour">r</span>

If you don't know regex, there are oodles of resources out there to get you started. You will be pleased to know that your requirement is very simple, so no worries there. Here are a couple of links:

regexlib.com

8 regular expressions you should know


You would need to use the DOM (or jQuery) to iterate through every text node in the document. Whenever you find the letter R, apply a transformation that wraps the letter in an appropriate element.

e.g. Transform the text node "art" into "a<span class="colored">r</span>t". This adds two new text nodes, "r" and "t", and the new span element.


The highlight plugin for jQuery is one option. Another option - especially since to-morrow - you might want to extend your highlighting into keywords or other terms is to use Google's Closure goog.dom.annotate Class. The beauty of this Class is that it will actually parse the dom tree properly and ONLY annotate the relevant terms. It will also allow you to EXCLUDE elements or elements with certain classes.

A common problem with annotations is that you can mess your HTML, if you are not careful.

For example the 'simple solution posted above'

var body = document.getElementsByTagName("body")[0];
var html = body.innerHTML
.replace(/(^|>[^<rR]*)([rR])/g, "$1<em>$2</em>");
body.innerHTML = html; 

will surely also capture terms in any style attributes. If you had this:

<p class="red">text......</p>

It will become

<p class="<span class="red">r</span>ed .....

that will break your html.

In general DOM parsing is 'slow', so try and avoid annotating the whole body of a webpage, ask yourself why you only need to highlight the R's? Actually I am curious why do you want to annotate the r's?:)


Plain JS solution without need of any 20kB JS library:

var body = document.getElementsByTagName("body")[0];
var html = body.innerHTML
               .replace(/(^|>[^<rR]*)([rR])/g, "$1<em>$2</em>");
body.innerHTML = html; // note that you will lose all
                       // event handlers in this step...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜