Monday, November 17, 2008
Using a Javascript Framework
Thankfully there are a lot of resources on the net to help and that is what this article will point you too. Some of the common resources I used to arrive at my decision. First off, this web site http://www.javascriptlibraries.com/ gives a great summary of the different javascript libraries, effects, and tools available today. As of this writing, it seems to be fairly up to date. So that's where I'd look if you're in the market for a library.
As far as performance goes, there is a great web site (slickspeed)that tests the selector performance of some of the top javascript libraries. It includes MooTools, JQuery, Prototype, YUI, and Dojo. This will be give you an idea of how the libraries may perform differently. In general, selector performance may or may not be important to you.
After spending a lot of time analyzing the different frameworks (Analysis Paralysis), I decided to use JQuery for the simple fact that it had great feedback and was easy to find great documentation and I was able to start using it right away. For a cross-browser library, it is incredible. It has so far solved nearly all the problems I've discussed in my blog. However, I will still continue to write about the different cross-browser issues I find as I replace the code with JQuery code.
Tuesday, September 30, 2008
Difference between parentNode and parentElement
Monday, August 18, 2008
Generic Events - Part 1
In my previous article, I discussed the different ways to bind to events in a browser agnostic fashion. In this article, I discuss how to create a generic function allowing you to bind to events in almost any browser.
In general you use either the Internet Explorer specific attachEvent or the W3C addEventListener functions when programmatically binding to events.
These functions are similar in behavior and we can make use of that to create a generic function that use either of these. One of the most frustrating things I've found with the W3C event support is the fact that it doesn't support the window.event object. Instead, it implicitly passes the event object to the function. I had to get that out and I will discuss it in future blogs, however, it has nothing to do with this article:-)
Here is the proper use of attachEvent in an IE browser:
document.getElementById("test").attachEvent("onclick", function(){alert('onclick was called');});
And here is the proper use of addEventListener in W3C browsers: document.getElementById("test").addEventListener("click", function(evt){alert('click was called'), false);
Note that you either use the name of a function or an anonymous function. As well addEventListener has an extra parameter for capturing events. At this point we will ignore that extra parameter by passing in false. Okay, so now that we know how to use them in the simplest case, here is a function that allows us to add events in a generic manner: function addEvent(elem, eventName, func)
{
if (elem.attachEvent)
{
elem.attachEvent('on' + eventName, func);
} else if(elem.addEventListener)
{
elem.addEventListener(eventName, func, false);
}
}
Note that addEventListener doesn't prefix events with the on keyword so when calling the addEvent function just pass in the event name and we append the on prefix as necessary. That's it for now. This function went a long way when converting my client's web site to support W3C browsers. In fact you won't believe how easy it is to use and begin replacing once you get started.
Sunday, July 27, 2008
Cross-browser Javascript Events
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
<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
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:
Enjoy!!
Monday, July 21, 2008
The cloneNode Problem
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:
<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.