Sunday, July 27, 2008

Cross-browser Javascript Events

So you're trying to convert your website from an IE specific site into a cross-browser compatible web site. You've probably noticed that the event object is not available in the current event as is the norm for Internet Explorer. In fact when supporting events in a cross-browser manner you must plan ahead.

There are three ways that you typcially hook up events in a browser. For example to hook up the onclick event you could add the onclick attribute to the tag you want to bind to:

<div id="test" onclick="doit();">Some Content</div>

Another way is to select the tag in javascript and use the onclick attribute as follows:

document.getElementById("test").onclick = doit;

and finally, the last method is to use the bind method which is called attachEvent in Internet Explorer and a similar event is called addEventListener in W3C browsers:

document.getElementById("test").attachEvent("onclick", doit);

The project I'm working on typically uses the first and last of these methods. In Internet Explorer, you can expect that the window.event object contains the current event. In W3C compatible browsers, for the first method above, you have access to a special event keyword that you can pass to your function. In the last two methods, the event is implicitly passed in.

Here's an example of using the event keyword for the first method:

<div id="test" onclick="doit(event, "myarg");">Some Content</div>

For the second method, here's an example of how to pass multiple parameters assuming that the event object is passed implicitly to the specified function:

document.getElementById("test").onclick = function(evt){doit(evt, "myarg");};


Finally, in the last example, here is how you'd pass the event object to W3C browsers:

document.getElementById("test").addEventListener("click", function(evt){doit(evt, "myarg");}, false);

That's it so far. In my next blog I show you how to take this information and create some rudimentary functions that will allow you to easily support events in a cross-browser manner.

Wednesday, July 23, 2008

Browser Compatible Mouse Events

As I continue on the path of converting an IE specific web site into a browser-agnostic web site I found that not all mouse events are the same. What I mean is, Internet Explorer 5.5 introduced the onmouseenter and onmouseleave event handlers. This is after everybody and their brother already support the onmouseover and onmouseout terminology which do exactly the same thing. By the way, don't get me wrong, I actually think the IE naming convention makes more sense. This is pretty much one of the most uninteresting and easily fixable browser issues I've come upon so far. The problem was finding the issue. When you think you know something that is so obvious like:

<div onmouseenter="dosomething();">Some text</div>

You continue to bang your head against the wall when it works in Internet Explorer but fails in Firefox.

So when you're fixing up your web site to make it fully cross-browser compatible. Make sure to use the classic onmouseover and onmouseout events.

Tuesday, July 22, 2008

How About a Quick Debug Output Window

One of the first things most Javascript developers learn is how to display an alert box. As they progress in their Javascript skills, they very soon realize that it's a bit of a black box and start to use those alerts to debug their code. Javascript has progressed over time and nowadays there are pretty decent debuggers. But often times you just need a console window to write output to. I wanted to write a very small little piece of code that allowed me to write debug output. This piece of code would allow me to simply paste it into the current Javascript I'm debugging and with one command, allow me to write to the debug window. I wanted to use Object Literal Syntax (AKA JSON) as well so I don't have to instantiate an instance of it. Well, with just a few lines of code, I was able to do that and I wanted to share it with you. It's not rocket science and would be fun to modify to see how much bang for your buck you could get out of it. Let me know what you think and even throw some suggestions out or add some code. Just paste this code somewhere into the Javascript code your are using:


var DBG = {
write : function(txt){
if (!window.dbgwnd){
window.dbgwnd = window.open("","debug","status=0,toolbar=0,location=0,menubar=0,directories=0,resizable=0,scrollbars=1,width=600,height=250");
window.dbgwnd.document.write('<html><head></head><body style="background-color:black"><div id="main" style="color:green;font-size:12px;font-family:Courier New;"></div></body></html>');
}
var x = window.dbgwnd.document.getElementById("main");
this.line=(this.line==null)?1:this.line+=1;
txt=this.line+': '+txt;
if (x.innerHTML == ""){
x.innerHTML = txt;
}
else {
x.innerHTML = txt + "<br/>" + x.innerHTML;
}
}

To write to the console, just add this line:

DBG.write("This is console output!!");

Enjoy!!

Monday, July 21, 2008

The cloneNode Problem

This is the first entry into the foray of problems that I found when trying to create cross-browser compatible javascript. As I mentioned before, a client of mine is converting their web site from Internet Explorer(IE) to a fully cross-browser compatible web site. That includes IE6 (uggg), IE7, Firefox 3.0, and Safari 3.1.

So anyway, the cloneNode problem. Here's the issue. I needed to replace the IE specific outerHTML function (which I'll discuss in another blog) with a cross-browser version. It turned out that the cloneNode function would make it very easy to do that. The problem was, in very specific cases (i.e. my case), it didn't exactly clone everything. You see, there's a bug (suprise), that appears to be in IE, in which when you make dynamic modifications to the HTML before calling cloneNode, it doesn't clone the node exactly. It just sort of copies most of it..... Blah. Well, here's some example code for you to try for yourself:

<html>
<head>
<title>Javascript Today - cloneNode bug</title>
<script>
function runit()
{
var node = document.getElementById("checkbox");
node.checked = true;
var wrapper = document.getElementById("wrapper");
alert(wrapper.innerHTML);
var cloned = wrapper.cloneNode(true);
alert(cloned.innerHTML);
}
</script>
</head>
<body id="bod">
<div id="wrapper">
<input id="checkbox" type="checkbox">
<a href="javascript:runit();">Click Me to See Bug</a>
</div>
</body>
</html>

Note that the code that is displayed in the alert is different each time. Perhaps there is an easy workaround. In a lot of cases the cloneNode function works soundly but don't depend on it. If you are only planning on using the innerHTML property then you may want to just take the innerHTML and assign it to the innerHTML of another element. In a future blog, I will show you how I duplicated the IE specific outerHTML function in a cross-browser manner. Hope this helps and talk to you later.

Sunday, July 20, 2008

Javascript Today

Lately I've found myself delving much deeper into the world of Javascript than I would have normally considered. You see, a client of mine wanted to convert their web site, which was written specifically to work with Internet Explorer, to be fully cross-browser compatible. I'm a long time developer and have made my living off of architecting and developing the server side components for software applications and web sites. But Javascript. Come on. I would lose my dignity. My programmer friends would endlessly chide me. But out of necessity I plunged deeper into the language and found out that there really is something to it. It's so unrestricted that it will make you rip out your hair. You can spend hours trying to fix or even find one little tiny bug. It can be extremely frustrating. But that's the point of this blog. To discuss my problems in hopes that you can use them to help you and keep you from spending hours on the same problems. Also, I will soon be starting the Javascript Today website with forums so we can all complain together:-) No, but the rest of the story is that I'm beginning to like Javascript. You can do so much with so little code. There are many libraries out there such as JQuery, Prototype, MOJO, and others that are very impressive and turns Javascript into an incredibly powerful language.