PPK (Peter-Paul Koch) of Quirksmode has been sharing his research into browser quirks for years, and this year he’s turned his attention to mobile browsers while doing a consultancy for Vodafone. That work has got him thinking about JavaScript events once again, and, as is his habit, the results of his research are freely available to the rest of us on Quirksmode (big-screen browser compatibility tables; mobile browser compatiblity tables).
PPK was in California last week and he was kind enough to visit Yahoo and deliver a tech talk outlining some of the interesting browser-event work he’s been doing. We’re happy to share that talk with you on YUI Theater. Slides from PPK’s talk are available in PDF form here.
PPK (Peter-Paul Koch): "JavaScript Events" @ Yahoo! Video
In Case You Missed…
Some other recent videos from the YUI Theater series:
- Jenny Donnelly: Hacking with YUI
- Nate Koechley: Professional Frontend Engineering
- John Resig: The DOM Is a Mess
- Nicole Sullivan: Design Fast Websites (Don’t Blame the Rounded Corners
Subscribing to YUI Theater:
Transcript: PPK, “JavaScript Events”
Peter-Paul Koch: Thank you for inviting me, once again, to speak at Yahoo!. I’m PPK: Peter-Paul Koch, but everybody calls me PPK. It’s a long story. I run a site called http://quirksmode.org, where you can find information about browser incompatibilities. And I have a Twitter account, obviously — who doesn’t?
And today, here at Yahoo!, I’m going to talk about JavaScript events. And I sincerely hope I can teach you something. That’s always the question when I speak for a Yahoo! audience, because you guys already know so much, I have no idea what I can contribute to it. But anyway, we’re going to give it a try. I am going to talk about JavaScript events.
It was about a year ago that I started some serious research into JavaScript events, and I published some compatibility tables. What I basically was doing, was testing the compatibility of all the common events, in all the common browsers. And there’s several things surprised me in that research. Some of these things are what I’m going to talk about today.
If you don’t know where my compatibility table is, here at http://quirksmode.org/dom/events. Use it to look up some complicated events stuff that you want to know about.
Today, we’re going to talk about four things. First of all, I’m going to give a quick introduction to the key events, because there is some confusion, sometimes, about exactly how they work. Secondly, I’m going to talk about the change event. It’s one of my absolute favorite events in the whole of JavaScript – unfortunately, it hardly works, and I’m going to talk about that. Thirdly, I’m going to talk about delegating the focus event. Event delegation, you’ll probably know about that – I’m going to give a very short introduction later on. Event delegation usually only works with a mouse and key event, but I’ve found a way to have it work with focus, and other interface events too, and I’d like to share that with you. And finally, I’m going to present the first results of my test of mobile events – and the results are weird, I can tell you that already. I’ll show you that later on.
But first: the key events. It all seems so simple. There are three key events – keydown, keypress, and keyup. And people generally think they know exactly when they fire. I’m here to tell you that it isn’t always as clear as you think it is.
Let’s go through some quick definitions. The keydown event fires when a key is depressed by the user, and it keeps on firing as long as the user keeps it depressed. That’s simple. The keypress event, basically that’s the same, except that it fires only when a character key is depressed – in other words, a key that will lead to a character being inserted into, say, a textarea. Finally, the keyup event fires when the user releases the key. Well, that’s all pretty simple.
Just to make absolutely sure that everybody understands – if I press, say, an ‘o’ key, or an ‘i’ key, or one of these strange bracket keys, both a keydown and a keypress event will fire. On the other hand, if I press special keys such as the shift key, or the arrow keys, only a keydown event will fire.
This theory of the difference between keydown and keypress originated with Microsoft. All the Internet Explorer versions actually use this difference between keydown and keypress. And Safari has copied it, as from version 3.1, I think, which was released about a year ago, maybe slightly more. The point is, here, that this theory is the only theory about the difference between keydown and keypress in existence. In contrast, Opera and Firefox just fire lots of events at you all the time, because it is tradition that it is both a keydown and a keypress event, so we should fire both whenever we see an opportunity. Which is fine, but it doesn’t explain why there should be two events, instead of just one: the keydown event. So that’s why I kind of like this theory of the difference between keydown and keypress.
So, let’s repeat it once more. Keydown fires when a key – any key – is depressed. Keypress fires when a character key is depressed. And as we can see here, it works in IE, and in Safari. Oh, and I don’t have Google Chrome items here yet, but assume that anything that works in Safari also works in Google Chrome. They are really quite close, these two browsers.
OK, so let’s move on to some practical questions. Usually when you write a script that detects user keys, he wants to know which key the user pressed, and do some interesting interface stuff based on that.
Now, there are two properties that any key event carries – those are the keyCode, and the charCode properties. And there are also two bits of data you might want to know about – the key code, and the character code. And the difference is, the key code is the actual code of the physical key the user depresses, and the character code is the code of the resulting character. So, if I press an ‘a’ key, I get key code 65, because the ‘a’ key has the code 65. But the character code is 97, for a lower case ‘a’. If I press a shift key, I get key code 16, because that’s shift – but I do not get a character code, because the shift key, by itself, doesn’t result in any character. Well, that sounds simple.
So we have one property – we have, actually, two properties, and two bits of data. And having one property containing one bit of data, and the other property the other, would of course, be far, far too simple. It would mean that you don’t need a specialized content engineers, that anyone can just write a key script, which is obviously not the idea.
So, what exactly is going on? It’s pretty complicated, actually, and frankly, I do not understand entirely why it should work like this. But it does work like this. The keyCode property. With a keydown event, onkeydown, it contains the key code – the code of the physical key the user depresses. Onkeypress, on the other hand, contains the character code – basically, the ASCII code of the character that appears on the screen. And this works in all browsers – except that in Firefox, onkeypress shows zero for key code; don’t ask me why. Then, charCode. Onkeydown, charCode returns zero, and onkeypress, charCode returns the character code. And this, too, works only in Firefox and Safari, because these are the only browsers to support charCode.
Let’s move on to something really practical. If you need the actual key that the user depressed, the physical key, use the keydown event and ask for the keyCode. That will work in all browsers. On the other hand, if you needed the character the user has just entered in a text area, or whatever, you should use the keypress event, and ask for either keyCode or charCode – one of them will contain the information you’re looking for in the browser.
Finally, sometimes you want to prevent the default action of a key. I’m especially thinking of arrow keys. Suppose you have a keyboard accessible drag and drop menu, and then you want the user to be able to manipulate the drag element by the arrow keys, and you want to cancel the default of the arrow keys – namely, scrolling the page. Basically, you should do that onkeydown, because, as I said before, keydown fires when any key is depressed, and keypress only fires when character keys are being depressed. Unfortunately, this does not work in Opera – and I must admit I did not test it the latest Opera, so it might have changed there. And preventing arrow keys in Opera is something I’m not going to talk about today, because frankly I forgot the answer.
That concludes the key events. It is not really complicated, all those key events, but you have to be aware of the difference between keydown and keypress.
Now, the change event. In theory, the change event would be absolutely wonderful to have, because the change event fires when the value of the form field is changed. Often, you want to detect everything the user does in a form – for instance, onformsubmission, you of course want to go through all form fields and validate them. But there’s also ways of making a form – or form fields, checkboxes for instance – a kind of menu that the user can use to go through a complicated interface. And what you want to do, always, is see what, exactly, that the user changed in the form. And in theory, the change event would be absolutely wonderful for that.
But usually, we are forced to use the focus or blur events instead – or maybe the click event, in the case of detecting a checkbox changes – because the change event doesn’t work quite correctly. We’re to distinguish three different cases. First of all, the change event of text fields; second, on select boxes; and third, on checkboxes and radios.
We start with text fields. And I suppose the user focuses on a text field, in any way, either by the mouse or the keyboard, and then blurs again. In other words, he moves on to the next field. In that case, no change fires, because there’s nothing that has changed – the value of the text field has not been modified. But if we change it slightly – if we say the user focuses on the text field, and then enters something, then blurs the text field, then a change event fires at the moment the user blurs the text field. Because the value of the text field has been modified, and that obviously causes a change event. This is all good; this works perfectly in all browsers.




















David Nesbitt is the VP of Engineering at 


Einar Paul Qvale works as a front-end developer for the Norwegian company 

We are using YUI in almost every area of the product. The core library is deeply integrated into the survey authoring and reporting platforms (
