Change Div Size, Color, and Location with the W3C DOM
The testchangecolorwithjavascript-void0-onclick.html file tests the using of the getElementById method to dynamically change div color, size, and coordinates in interesting ways. The green and yellow boxes get their width and height changed—slowly, the blue box gets its color changed in a way that simulates a colored curtain being drawn in front of it, and the black box seems to jump away like a frog whenever you try to catch it.
First, though, let’s look at the divs. Below is the green box div and the div of the text link that activates it and a status bar function. The text link below uses the void keyword. It is a good idea to get in the habit of using this keyword around any script code that you call in a link. This special JavaScript keyword tells the browser to ignore any return values—some of which could cause big problems. Or, simply put, the link below is a "do nothing" link there only to make clickable text. The onMouseOver event handler is there only to run the wipe() function, and no, we’re not going to smirk about that. Not a bit. Okay, only a little. This function clears the status bar which otherwise will tell visitors javascript:void(0), which they will not really understand at all. The onClick event handler runs the changewidth() function. In the green box div, the id is "s" and the getElementById method will use this for CSS style property adjustments.
<div style="position:absolute; left:400px; top:30px;"><a href="javascript:void(0)" onMouseOver="wipe();return true;" onClick="changewidth();">Change width.</a></div>
<div id="s" style="position:absolute; top:50px; left:400px; width:100px; height:100px; background-color:green; text-align:center;"><br><br><br><b>div box</b></div><BR>
The changewidth() function is set up to do its size change slowly. We could easily have just given the new width and that would be that. But what fun is that, right? Before the function is ever called, the x variable has already been set to 100, q was set to 5, and the f flag was set to 0. The f flag flips on and off every other click of the link, which makes this function cause the box to expand or contract. We’re changing the width from 100 to 200 and back to 100 again, which explains why x is set to 100 from the get-go. Five is the value of q, our increment value.
Note that it gets its sign changed every time the function runs, since we grow and shrink the div alternately. And finally there's the setTimeout. We've all wondered if this was needed and why, what good is it if you want it to have a 0 argument representing milliseconds, and whether other conditionals or even loops work with it, right? If not, you're a conservative; if so, you're a liberal; and if you not only wondered about it but experimented gleefully—interrupted only by your cackles and groans—until you figured much of it out, you're a programmer. We’d love it if any of you out there in JavaScriptland can add any extra insight to these matters—contact us. As Ross Perot once said during the presidential debates, "I'm all ears."
Anyway, here's what we learned: Using the while or for-next or do-while loops can get your values from 100 to 200 with incrementing just fine, but you can't use setTimeout or setInterval methods. And no matter how you try to slow down the action with 0.1 increments that only make the width a pixel bigger once every 10 loops, it won't change the fact that the actual change to the div only occurs at the end of the loop—when 100 is suddenly 200. Why won't the incremental object property value incrementing result in incremental div box changes (incrementally)? It works with conditionals if and switch (although the latter isn't a good choice), and both of these conditionals work with setTimeout or setInterval methods.
What gives? Not being engineers, we can't exactly say. They could have made JavaScript allow these div increments within loops if they'd wanted to badly enough. Of course, there would be no timer methods to go with the loops, since the setTimeout or setInterval methods call the function they're in repeatedly while they're operating. Variable = setTimeout("function()",milliseconds); is how they must work. But if you call the function while in a loop, you get errors and crashes:
function whatever(){
while(x<201){update div width code; t=setTimeout("whatever()",0);}}
Of course, one problem here is obvious. Every time the timer recalls the function you're restarting the while loop infinitum. But if you 86 the timer, the code quits giving errors and simply changes your box size to 200. This problem is more challenging. If you monitor values with window.status=x; you see the x getting bigger while the div doesn’t. This wouldn’t happen in BASIC on a PC in DOS. So it’s about the way JavaScript does its thing. Any comments from the peanut gallery?
function changewidth(){
if(x>200&&f==0){f=1;return;}
if(x<101&&f==1){f=0;return;}
if(f)q=-5;if(!f)q=5;x=x+q;
e=document.getElementById("s");
e.style.width = x + 'px';
t=setTimeout("changewidth();",0);
}
Next we’ll look at the changecolor() function. Just to be cute we stuck in the code for cross-browser compatibility, in case there's someone in Tasmania who hasn’t seen it yet. Ignoring the first if…return;} code, the comments say which browsers each code block is for. The last code block is for Netscape because it says !document.all (not IE), but since it’s the getElementById method, it can be used by IE5+ too, if
!document.all is 86ed. You can see why we stuck in the if(p=="r"&& document.getElementById)… stuff at the beginning so we wouldn’t need to mess with obsolete document.all stuff, even though you need to pretend not to see it for purposes of cross-browser coding examples. We italicized it and changed its color to make it easier to ignore. The bottom line is that the getElementById stuff is faster, better, and more dynamic JavaScript, and the faster we dump the old junk, the better off we’ll be.
function changecolor(newcolor){if(p=="r"&& document.getElementById){document.getElementById('r').style.backgroundColor = newcolor; return;}
if(document.layers){ // browser="NN4";
document.layers["q"].bgColor = newcolor;
}
if(document.all){ // browser="IE";
document.all.q.style.backgroundColor = newcolor;
}
if(!document.all && document.getElementById){ // browser="NN6+ or IE5+ if you're willing to dump the !document.all stuff";
document.getElementById('q').style.backgroundColor = newcolor;
}
}
And next, for your viewing pleasure is the big blue box div and the text link that runs it. Enjoy the show: The text div is first. Its code is like what we've discussed above, but it also has a double-click event handler that causes a slow drawing-of-a-curtain effect. After that comes two divs, one covering the other (cascade rules are that the last one declared gets the highest z index so it’s on top). The one doing the covering is transparent, so its coverage potentials are about on par with a see-through blouse in a wet t-shirt contest.
<div style="position:absolute; left:10px; top:10px;"><a href="javascript:void(0)" onMouseOver="wipe();return true;" onDblClick="changecolorslowly();" onClick="changecolor('#FF00FF');">Change background color.<br>Use click, but also doubleclick.</a></div>
<div id="q" style="position:absolute; top:50px; left:10px; width:200px; height:200px; background-color:red; text-align:center;"><br><br><br><b>div box</b></div><BR>
<div id="r" style="position:absolute; top:50px; left:10px; width:200px; height:200px; background-color:transparent; text-align:center;"><br><br><br><b>div box</b></div><BR>
The function changecolorslowly() is eager for our perusal, next. It changes the blue div to mauve instantly if you click, but back to blue slowly if you double-click, which causes a slow drawing-of-a-curtain effect. The latter method is similar to the changewidth() function’s width increaser code. It operates on the div on top, not the bottom one, and this top div first gets its width changed from 200 to 40 (20 gets added to the w variable’s initially declared value of 20) and its color changed to blue, and then the width keeps incrementing 20 until it gets to 200.
function changecolorslowly(){
if(w>200){w=20;return;}
w=w+20;p="r";
e=document.getElementById("r");
e.style.width = w + 'px';
e.style.backgroundColor = 'blue';
t=setTimeout("changecolorslowly();",0);
}
Finally there's that playful little devil we like to call moveaway(). The div that calls it uses onMouseOver="javascript:moveaway()" to activate it. Notice that this code is in a div tag, not in a link, image or button—one of which would have been the necessary container before the W3C DOM. We use the m flag to signal that one of the first four if conditionals has been evaluated as true so its coordinate adjuster has been implemented. If no such adjustment has transpired, m is 0 and a random change is made in the div’s screen coordinates. Note: if(!m) = if not m = if m is 0. The term !m doesn’t mean we’re excited about m. (M.M. [Marilyn Monroe] yes, but not m.) Okay, now, the first four if conditionals keep "the boat off the rocks," if you will, or the div off the window edges, if you won't. We won't. Why should you? Anyway, off the rocks means relocating the div back towards the screen center. Finally, let’s look at the way we used the random method of the Math object. This method gets a random decimal number between 0 and 1, so we multiply it by the top number (100) of the range (0 to 100) we want our desired random integer to be in, and we get our integer. But, we lied; we don’t really want our integer bigger than 50, our div size. So we subtract 50 and the number that we don’t want (0 to 100) turns into the number (-50 to +50) that we do want: a number that can toss the div in any direction whatsoever because n and o will be unequal and either can be positive or negative numbers.
function moveaway(){m=0;
e=document.getElementById("z");
if(h>700){h=h-50;m=1;}
if(h<50){h=h+50;m=1;}
if(v>350){v=v-50;m=1;}
if(v<50){v=v+50;m=1;}
if(!m){n=Math.random()*100-50;o=Math.random()*100-50;h=h+n;v=v+o;}
e.style.left = h + 'px';
e.style.top = v + 'px';
}
Understanding computer science, and specifically coding, takes time and learning to accomplish even a little understanding. An instructional technology masters degree is an obvious great first step, due to the degrees overall coverage of the subjects and in depth teaching of important practices.