Busted Mug

A blog that documents solutions to the most frustrating problems that occur during development in technologies such as Java, XML, AJAX, SQL, CSS and others that make me want to throw my coffee mug against the cube wall.

Monday, March 19, 2007

Busted Mug: Dynamic Assignment of Event Handlers - A generic rollover event

Busted Mug: Dynamic Assignment of Event Handlers - A generic rollover event - Gosh, what was I thinking? You've gotta preload those rollovers! Here's a revised version using a dynamically created function as the dynamically created event handler. Say that ten times fast...you'll probably want to dynamically go create yourself a cup of coffee ;)
//bch: better code for rollovers
function start(){
    var els = document.getElementsByTagName('img');
    for (i=0; i<els.length; i++){
        if(els[i].className 
== "rollover"){ 
            var tmp 
= new Image();
            
            //save out source
            tmp.src 
= els[i].src;
            outs[i] 
= tmp;
            
            //save over source
            tmp.src 
= els[i].substring(0,src.length-4) + "_over" + src.substring(src.length-4);
            overs[i] 
= tmp;
        
            //set event handlers w/ dynamic functions
            els[i].onmouseover 
= eval(new function (){ this.src = overs[i].src});
            els[i].onmouseout 
= eval(new function (){ this.src = outs[i].src});
        }
    }
}

Friday, March 16, 2007

Double killer delete select all


Oh it burns so good! It reminds me of this classic windows 98 debachle

Mystery white space before a table

I was trying to debug some mystery white space that was appearing on a page before a table. For some reason the source code showed nothing before the table, but the display didn't agree.

Using FireBug (an add-on to firefox that i HIGHLY recommend) I was able to see that FFox thought that white space should be there because of some BR tags. Curious. I couldn't find them anywhere.

Finally tracing through I ran into a much more obfuscated version of this:

out.println("<table>");
for 
(int i=0i<contents.lengthi++){
    
out.println("<tr><td>" + contents[i] + "</td></tr><br>");
}

Note the BR on the end there. That's not valid. Apparently FFox handled this bad code by kicking the BRs to the head of the table. A simple fix to a problem that had me in mug busting mood BIG TIME.

Monday, March 05, 2007

Dynamic Assignment of Event Handlers - A generic rollover event

Rollovers are so often done badly and you have to write code for every image. No more. It is much better to use some code as follows to make a generic function and then apply it generically as I have using the class attribute.

<html>
<head>
<script>
    
function start(){
        
var els = document.getElementsByTagName('img');
        for 
(i=0i<els.lengthi++){
            
if(els[i].className == "rollover"){
                els[i].onmouseover 
swap;
                
els[i].onmouseout swap;
            
}
        }
    }

    
function swap(){
        
var src = this.src;
        var 
pos = this.src.indexOf("_over");
        var 
tmp = new Image();
        
        if
(pos == -1){    
            tmp.src 
src.substring(0,src.length-4) + "_over" + src.substring(src.length-4);
            this
.src tmp.src;
        
}else{
            
this.src src.substring(0,pos) + src.substring(pos+5);
        
}
    }
</script>
</head>
<body onload="start();">
    
<img src="x.gif" id="hi" class="rollover" />
</
body>
</html>

Doh! Be sure to read the update to this post, too. I forgot to preload those images :x

Friday, March 02, 2007

The External JavaScript File (.JS) Caching Dilemma

The apps I work on always seem to run into issues because users have cached old versions of our external javascript files. I'll add a call to a new function defined in a .js to a page and the user's browser will puke because it is using the cached version. No good.

While looking for a way to prevent my .js files from being cached I ran across this: DivineNTD.com Journal: Preventing JavaScript File Caching

That doesn't really solve the problem since you're just changing source, but I'll take it. It will keep your .js file at the newest version. Dirty, but effective.

To push the solution forward a little, what I've decided to do is to add a member to a static class that is loaded in the constructor. I then create one of these when the app is started. Since I am working in Java and it is compiled, the app will be restarted when new code is introduced. This means that whenever the app is restarted, the date changes. I append THAT, after a ? to my .js addresses and voila: .js files are flushed out of the cache only when they are changed. ;)