JavaScript mouse wheel in 2013

Mouse wheel support is one of those things that have long relied on proprietary non-standard events. Now that I’ve been having a (quite passive) look around for new wheel supporting snippets of code around the web in places like CodePen or some dev blogs I’ve noticed that a) a lot of people dev on Chrome, and b) if Chrome doesn’t use the standard way, many don’t bother to even lookup the standard method and instead rely only on non-standard stuff, assuming what they’ve used is the standard way.

Mouse wheel stuff can be quite deceiving. There is the Internet Explorer 6 originated mousewheel event which is supported by everything except Firefox / Gecko. The problem with this event is it’s name: by it it seems like it would be a standard event. And this is not correct, which is also why I think Firefox got this right by not supporting it and by using a clearly non-standard name instead: DomMouseScroll.

But these days we also do have a standard event. The name of it? The wheel event. And it is supported since Firefox 17 and Internet Explorer 9. The good thing about this new event is that if we don’t need to support Firefox 3.6 (which is the last version that didn’t have the automatic upgrade feature) then we really only need to support two events: wheel and mousewheel.

Implementing a modern cross-browser solution

If you’re using jQuery and don’t mind plugins then there is already a quite excellent normalizing mousewheel plugin. Just bind yourself to one event and you get (nearly) the same results in a wide range of browsers and platforms. Just for a note though I don’t fully agree with all of the choices in the plugin’s internal logic: if wheel event is implemented in Webkit then (if I’ve read correctly) the old proprietary methods are currently preferred over the standard event. This is minor, but I think one should always prefer the standard way unless there is a bug in implementation.

However there are people who like to do things without using a library or a framework. So here I go through two implementations and also add notes about some gotchas.

Minimal implementation with DOM Level 1 events

If you are the only person that ever touches the code and you don’t need to care about constant development or future changes by others, which is the case for most personal sites, then I think there is nothing wrong in using the old event model. It is simple to use, every single browser supports it 100% and it works fine if you don’t want to go around and apply multiple wheel event handlers to the same element. And most often we really don’t need to.

Here are a few pointers for the simplest implementation:

  • Use onwheel as the main handler. Firefox is the only browser that actually does this right now.
  • We cancel bubbling in onwheel event so that the other wheel events are not triggered.
  • All other browsers rely to the onmousewheel, even IE9 and IE10 (they only support wheel event via addEventListener).
  • We make event object in onmousewheel event compatible with onwheel event and then call the latter.
  • To ensure more useful delta data we normalize the value.

With all of this the resulting skeleton code is simple and short:

Check out this Pen!

And if you like eye candy then this is more pleasant to look at:

Check out this Pen!

It uses the same core idea, just has more features around it for cross-browser, cross-device usability.

Implementation with addEventListener

addEventListener is the preferred way to handle the event. However there is one notable issue that forces us to consider attachEvent: Internet Explorer 8 always works as if preventDefault() is called if mousewheel event is listened using addEventListener. There is no way around this: we have to sniff for IE8 or default to attachEvent first. As much as I dislike it I’ve chosen to sniff, because we can detect IE8 reliably and the bug is only in IE8. If you always want preventDefault() or if you don’t need to support IE8 then you can throw IE8 stuff away.

We do not add support for Firefox 16 or older here. Adding extra handler for it isn’t too hard, just copy mousewheelCompatibility and implement DOMMouseScrollCompatibility and add a listener to it. Also you have to use e.detail instead of e.wheelDelta.

Check out this Pen!

And there you have it: mouse wheel solution that prefers a fresh standardized wheel event with a fallback to mousewheel event if it isn’t supported.

Comma separated values

Saw some CSV polyfill stuff posted at CodePen. Did some CSV stuff years ago with VB6. It was quite fast, although the code wasn’t very short. That tends to happen when you have almost full control of memory and want to make things fast. With a language not designed for that kind of stuff.

This CSV element polyfill idea however is quite nice. The original author that did the pen linked above didn’t initially have any support for quotes. I wanted to do something that can take almost anything and still work, even if there are line changes within the quoted values, so I started bothering my brains with JavaScript. I’ve read about it a lot in the past few days (thanks to Secrets of the JavaScript Ninja), but I haven’t really done anything practical for a little while. So here we go:

Check out this Pen!

I have still some work to do. I haven’t read much about regular expressions yet. I know somewhat how they work but I rarely push my brain to understanding them in detail. It’ll probably be one of the more challenging parts of the book for me. RegExps just seem the kind of thing that works so different to my own brain logic that it makes it hard to “get it”. However for the first time in my life I actually have a good reason to learn it so I’ll eventually get my head into it.

The thing that is missing is single quote support. You can have multiple line values if you use double quotes, but that doesn’t work with single quotes. Not just yet. I want to have both supported the same time even though there probably aren’t that many CSV files that are so absurd that they’d use both! However CSV is a very “free” standard and it varies so much between users that it makes your head sore when you want to throw your best shot at supporting everything that people have done with it.

Understanding “Body Border, Rounded Inside”

A little over a week ago Chris Coyier posted about this over at CSS-Tricks. The post has gotten lots of suggestions but only very few of them actually work the intended way. I got it wrong myself when I posted my first reply on the issue, but I kept going on until I had the “perfect” solution. Too bad the “perfect” solution is also a complex one and needs quite a bit of CSS. We need a lot of (pseudo) elements to create the effect.

So what is so hard about it? Why we can’t use a simple single element solution?

Check out this Pen!

Initially things seem to be alright. However when you start scrolling you’ll notice the content is above the border. Then you go ahead and fix that by changing the z-index of the element creating the border. Now you have a new problem: while content is visible and you can read it, you can’t select any of the text or interact with anything on the page. There is no way around this issue: you must use more than one element.

I guess “body border” can also be confusing as a term, because what we really mean by it is “viewport border”. A lot of the suggestions ignore the need for fixed positioning.

Become a ninja

As I’m soon starting off as a “real” front-end web developer I decided to do something that is very unlike my usual self: I bought a book. After looking around for good candidates I ended up finding Secrets of the JavaScript Ninja, and I must say this book is just the right thing for me. While I yet haven’t read the entire book and I’m only as far as chapter 4 I can already tell a lot of the stuff is really useful in giving the understanding of the whole nature of JavaScript that I previously only learned in bits and pieces.

For me the explanations actually go a bit too much in-depth and I’m perfectly happy reading only the code samples once I’m done going through some of the initial introductions to each concept. So I guess I’m ignoring roughly one third or fourth of the whole content of the book. This is of course not the fault of the book, it has to draw the line somewhere and giving a bit too much is often better than giving too little.

It is nice how some concepts that seem to be hard-to-do are actually quite simple in JavaScript. At the moment the most powerful new things for me have been apply and call. Some of the samples are quite genius and I can see how creating a fake (or custom) Array or wrapping Math.min and Math.max for arrays will be useful in the future.

I might return to the subject once I’ve read the entire book. For now I’m quite happy for buying this book as it reduces the amount of time I need to spend learning new stuff by trying things myself.

Because I love Final Fantasy IX

Okay. After some thoughts I’ve abandoned the idea of black’n’green theme. I’d need more experience on it than I can spare time so instead I jump to something I know and love: Final Fantasy IX. The design will take gradually steps to FF9 like direction. I probably throw in some more or less cool effects that are somewhat unusual on a regular web page. This is my playground so I can try things that wouldn’t be OK on a regular site.

Rounded Body Border

Chris Coyier posted this problem over at CSS-Tricks and also did come up with a solution. Initially it seemed like a lot of code (and I missed that the border needs to stay fixed in place) and then I didn’t like how the scrollbar was moved further inside to the page so I started working on the issue.

Check out this Pen!

I’m too tired to write about this more than this so I let the code speak for itself. (And I still need to get a stronger inspiration for the design of this site. Maybe next week…)

Update!

Now even more impressive:

Check out this Pen!

Pixel perfect webfonts

So, I wanted to do quite a retro design here. My very first homepage had green text on black background. While I have dropped the idea of having everything as green text to avoid having too much of it (especially as it is the link color) I have otherwise kept things quite simple. I didn’t want to spend a lot of time creating an entirely new WordPress theme so HTML is almost untouched in comparison to what you get out-of-the-box. That limited my originality and I ended up being happy with a very boring layout. But this doesn’t mean there isn’t anything to see!

I had quite interesting challenges when I ended up using pixel fonts instead of anything fancy and modern. The main problem was Firefox: it seems to be overly aware of subpixel rendering, to the point it even smoothes pixel fonts! So I had to be extra careful with the design to make sure all measurements are pixel perfect (no fractions), even if I do use em units for almost everything. This resulted into a bit of JavaScript (or to be precise, jQuery) to center the page. If I let Firefox to center the page element then it is most likely the page content ends up having subpixel positioning and that results in smooth fonts. So with a bit of JavaScript I do manual positioning and also undo default CSS centering with a float, yet the design is not dependant on JS.

The fonts I use are:

Reorganizing myself on the web

It’s been a while since I had a personal type of web site on the web. I can’t recall why I ended up discontinuing my earlier English websites; I remember I did it, but the reasons just don’t come back to my mind. I haven’t been thinking about it enough over the years, I guess.

In short I have a lot of interests around computers. This involves web development and design, other programming, interest on a bunch of old games that are considered retro these days… and as such I chose these as my primary points of this website. In the future one should expect to find stuff that is related to the old games as well as some thoughts and stuff on HTML5, CSS3 and JavaScript. Maybe even Clojure and ClojureScript if I really get the time to start learning it!