About a week back I began work on a couple of UI Javascript effects. An auto-completer, and an accordion. I know libraries come with these plug-ins pre-defined, but they’re heavy. Plus, I wanted to take up the challenge of making one on my own, so that I’d get to learn a few things as well. And boy, learn I did.
I thought I’ll share the few annoyances I ran into, which will maybe change someday.
Adding events
Adding events have always been a C0C0C0hex area. I’ve seen multiple tutorials which say that the addEventListener property is the way to go when working with scripts. This allows more than one function to be called when an event is triggered. The alternative is to use attributes like onkeyup and onmouseover, and assign a function to that. But consider a scenario as such:
<input id='foo' value='clickme' onclick='javascript:alert('inline'+this.id)'/>
<script type='text/javascript'>
document.getElementById('foo').addEventListener('click', function(){ alert('js'+this.id); }, true);
</script>
What do you think will happen?
If you execute that bit of code, you’ll see that the Javascript attached event handler triggered first. Now I didn’t know that. I’ve always thought inline definitions got highest priorities, because that’s how pretty much every other language works1. It seems I was wrong.
You will not find an explicit explanation of this anywhere on the web, but this priority model seems to be uniform in HTML/DOM handling. If you remember your mathematical sets, then speaking in those terms: mutually independent statements get clubbed together, whereas conflicting statements are ordered by last-defined. That being a more general statement, it simply means that whatever you defined last will be executed first. Also note that there is no way to change the order of the above definition. You cannot define the event handler before then element is defined in the DOM. I’ll probably write a small primer on this later.
The cross-browser issue
If you run that script in IE (I’m assuming you’re like me and ran it in Firefox first, which you should always anyway), you’ll see that script never executes. It’s something that struck me at 12 o’ clock in the night lying in bed, which made me feel rather stupid, and hate IE even more.
IE has a different way of adding event handlers. It uses the (very limiting) attachEvent property. I say limiting because it doesn’t allow the event instance queue, which can be used to cancel events (more here). But more importantly, it means two separates blocks of code for two different browsers. Unfortunately, Opera uses the same property as IE, but we don’t bother with Opera, do we? ;)
That issue apart, when you do use the modified code:
<script type='text/javascript'>
document.getElementById('foo').attachEvent('onclick', function(){ alert('js'+this.id); });
</script>
You’ll see an undefined pop-up. That’s the second IE annoyance, but it’s one that I haven’t understood properly this in IE points to the event, not the object triggering the event. The this pointer in Mozilla browsers, when used from event handlers, points to the object which triggered the event. So this.id will give us what is expected. The problem lies in the different properties that a DOM object holds in the different browsers. You can give it a go here. You’ll see what I’m talking about.
I don’t know why this is the case though It’s because IE is a conniving, non W3C standards following browser. Period.
JQuery
Finally, the framework I’ve been using for the past whatever weeks. The issue mainly was size over features. Taking nothing away from Prototype, I think it’s too big for everyday use. Even though the script.aculo.us library is dependent on it, there are libraries like moo.fx that do a similar job but with oh-so-tempting sizes.
Finally, it came down to either Mootools, or JQuery. I picked the bare-bones framework to work with, deciding that it was about time I started with Javascript from scratch, all over again. Coding back-ends for projects had almost made me useless when it came to interface and UI development. Mootools is a good alternative, of course. It’s got everything Prototype does (including advanced class-handling), but with a little bit of reading and personal tutoring, you can do all those things yourself, and trust me, you’ll be glad you learnt it rather than depend on a framework to handle the brunt. After all, it’s the basics that count.
So, I’ve been using and will continue to use JQuery for all my future escapades into JS land, a couple of which I’ll be revealing in the month to come. Thanks to John Resig for the wonderful element selectors (they’ve really made life easy), and I hope my ramblings till now will help you sometime when you’re close to banging your head against the wall.
-
Memory constraints being a reason. We know inline functions are inherently small in size, hence giving priority to their execution makes sense. You could be a stuntman programmer and try inlining a particularly large function, won’t make a difference, but language developers expect some common-sense. ↩
No Comments
Leave a comment
RSS feed for comments on this post. TrackBack URL