reptile7's JavaScript blog
Tuesday, November 26, 2013
Coloring by Character, Part 2
Blog Entry #307

We return now to our discussion of the Java Goodies Multi-Colored Text script. Continuing from the previous post, we have in place
(1) a to-be-colored text string and
(2) a hexa array of hexadecimal digits
and we are ready to color the text string with the colours( ) function, which is called and passed text just before the page has finished loading.

function colours(text) { var posa = 0; var posb = 1; while (posa <= text.length) { ... } }

The colours( ) function first initializes posa and posb variables that will respectively serve as indexA and indexB delimiters for various text.substring( ) operations. The rest of the colours( ) function comprises a while loop that walks through and processes the text string.

Random bits

The while loop body begins with six statements that generate random integers in the range running from 0 to 14, inclusive.

var r = Math.floor(Math.random( ) * 15);
var rr = Math.floor(Math.random( ) * 15);
var g = Math.floor(Math.random( ) * 15);
var gg = Math.floor(Math.random( ) * 15);
var b = Math.floor(Math.random( ) * 15);
var bb = Math.floor(Math.random( ) * 15);

Near the end of the colours( ) function, the r-to-bb variables are plugged into the hexa array to give random hexadecimal digits that are concatenated in order to form a hex code for coloring a text character. FYI: If the preceding statements were placed before the loop, then every text character would have the same color.

When I first looked at these statements I thought, "Why aren't we using Math.floor(Math.random( ) * 16) expressions so we can go all the way up to 15/F?" It subsequently occurred to me that stopping at 14/E ensures that all of the text characters are dark enough to show up on a white background.

Tag encounter

Next we have an if statement that handles HTML tags (the text string could begin with an HTML tag, after all):

if (text.substring(posa,posb) == "<") { var posaa = 0; posaa = posa; while (text.substring(posaa,posb) != ">") { posaa++; posb++; } document.write(text.substring(posa, posb)); posa = posb; posb = posa + 1; }


Here's what happens if posa indexes a < left angle bracket character:

(1) A posaa variable is initialized to 0 and then given posa's value.

(2) posaa and posb are via a while loop stepped forward through the text string until posaa hits a > right angle bracket character (the end of the tag).

(3) A document.write( ) command writes the tag (text.substring(posa, posb)) to the page.

(4) posa is laddered* to posb's position; posb is increased by 1.
(*Chutes and Ladders is my favorite board game.)

It follows from the above that text should not contain any stray < characters: a
var text = "Experts agree that 4 < 5 most of the time.";
string would give rise to an infinite loop, and you definitely don't want that.

A new, random color

We are at long last ready to color text's #PCDATA text; each character thereof is colored and written to the page one at a time by the following code:

document.write("<font color='#" + hexa[r] + hexa[rr] + hexa[g] + hexa[gg] + hexa[b] + hexa[bb] + "'>");
document.write(text.substring(posa, posb) + "</font>");

Each digit of the color attribute's hex code value is randomized - it doesn't get any more random than that. In contrast, the HTML Goodies JavaScript Script Tips #81-83 script, with which I compared the Multi-Colored Text script last time, randomly colors text characters via a defClrsArray color array that is defined in advance.

The colours( ) function concludes by moving posa and posb to the next character(s):


Other coloring formulations

If you're not happy about using a font element - I'm not happy about using a font element - then you can replace it with a corresponding span element:

document.write("<span style='color:#" + hexa[r] + hexa[rr] + hexa[g] + hexa[gg] + hexa[b] + hexa[bb] + "'>");
document.write(text.substring(posa, posb) + "</span>");

The Script Tips #81-83 script uses the fontcolor( ) method of the String object to color its charColor characters. If we wanted to use the fontcolor( ) method to hexa-color the posa character, here's how we'd do it:

text.substring(posa, posb).fontcolor("#" + hexa[r] + hexa[rr] + hexa[g] + hexa[gg] + hexa[b] + hexa[bb])

However, Mozilla discommends the fontcolor( ) method: Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future. So we should probably go with the span approach.

Adjacent HTML tags

Let's go back to the Tag encounter section's if statement for a moment. If at the end of the statement posa indexes a < character, then that character, and whatever follows it, will be colored and printed out by the code in the preceding section. Erik inserts a space character between the adjacent HTML tags in the text string to preempt this situation and ensure that the <font size='9'>, </blink>, <u>, and </b> tags are perceived as markup and not as #PCDATA text. Alternatively, the interstitial spaces can be thrown out if we place the preceding section's code in an if (text.substring(posa, posb) != "<") { ... } clause or more simply an else { ... } clause.

More structure

Netscape 4.x may not support the innerHTML property but all modern browsers do, giving us the green light to put the to-be-colored text in a div or p element:

<div id="colorDiv">This JavaScript shows every letter of text ...</div>

The colorDiv div's innerHTML can be assigned to text and passed to the colours( ) function when the page loads:

window.onload = function ( ) { var text = document.getElementById("colorDiv").innerHTML; colours(text); }

In the colours( ) function we can build the colored/formatted string as a colorString string

var colorString = ""; ...
// For adding an HTML tag:
colorString += text.substring(posa, posb); ...
// For adding a colored #PCDATA character:
colorString += "<span style='color:#" + hexa[r] + hexa[rr] + hexa[g] + hexa[gg] + hexa[b] + hexa[bb] + "'>"
+ text.substring(posa, posb) + "</span>";

and finally assign the completed colorString string to the colorDiv div's innerHTML.

document.getElementById("colorDiv").innerHTML = colorString;

Moreover, putting the to-be-colored text in a div or p element takes care of the original script's don't use quotation marks [in the text string] limitation.


Click the button to randomly color the text above it.

This text is bolded.
This text is italicized.
This text is underlined.
This is just plain text.

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)