I transitioned to a game team at work a couple of months ago. One of the reasons why I chose that particular team was that they were willing to let me do front end work, despite my lack of experience in that realm; this excited me because I figured I’d learn more that way than doing back end work. Also, I’m working on one of our older games; most of our new games have Flash front ends, but this game’s front end is in JavaScript, so working on this game does double-duty in that it helps fill in a notable gap in my programming experience.
So: JavaScript. It’s pretty cool. I’m glad to be working in a scripting language, I’m glad to be working in a dynamic language. I can’t say I’ve developed particularly good JavaScript style yet: in particular, the prototype-based inheritance model opens up a wider range of choices than I’m used to, choices where I don’t see a compelling reason to follow one path or another. I’m hoping that that will gel more; in the mean time, every once in a while I write some code that involves the fact that methods are properties just like any other, letting me do some cool code modification that I wouldn’t be able to do as easily in most other languages that I’m familiar with. (Though I suppose most of the time when I’m doing that it has a sort of Ruby monkeypatching feel.) And, given a desire to do that, a prototype-based system makes a fair amount of sense. I’m also not entirely sure how to react to member variables being public; for now, though, I’m just going with the flow and using that when it makes my life simpler, rather than being scrupulous about adding getters when I don’t need them or using closures to hide member variables entirely.
So, fun stuff; this doesn’t mean that I’m completely in love with the language, however. It has a few flat-out bugs; the worst is that, if you’re in a method and create an anonymous function, then, inside that function, ‘this’ is bound to the function object instead of the object whose method you are evaluating, which is never the behavior you want. (For that matter, having to type ‘this.’ all the time isn’t too thrilling, either.) And, coming from Ruby, the built-in tools for working with collections are surprisingly weak; I’m glad that I have jQuery.each and jQuery.map to help me, but that should be built into the basic language. (It doesn’t help that the callback that jQuery.each wants has its arguments in the wrong order, either. Hmm, maybe I should be looking into Prototype more?)
Of course, front end work doesn’t just mean working with JavaScript: it means working with HTML and CSS. And what I’ve been completely surprised by is how much I’m liking CSS. Previously, CSS had struck me as a basically good but banal idea, without as many tools to help me not have to repeat myself as I’d like. But now I’m really getting into the concrete benefits of the CSS Zen approach, where identical HTML is getting styled in different ways based on the context.
This really hit home when I was reworking the game’s keepsakes/scrapbook interface. Both of those pages want to display collections of items; and, on both of those pages, we make a distinction between featured collections (with a green background) and regular collections (with a blue background), leaving us with four different contexts. What I ended up doing was writing a single function that will display all the items in the collection; but outside of the HTML generated by that function I put a div with a class saying whether the collection was regular or featured, and outside of that div I put another div saying whether I was on the keepsakes page or the scrapbook page.
So then I would write simple CSS rules that specified the parts of the layout that were identical in all four contexts: e.g. pictures had the same size no matter where you were. But I’d write two rules for the backdrop: if it was contained within the featured div, the backdrop should be green, while if it’s within the regular div, it should be blue. And there were some bits of the decoration (e.g. buttons beneath the items) that I didn’t want to show at all on the scrapbook page; I’d still generate the HTML for them, but I’d include appropriate CSS selectors to get it not to be displayed on the scrapbook.
All of this resulted in nice-looking JavaScript generating nice-looking HTML, with CSS rules being easy to figure out, and making it as easy as possible to get a consistent look. Way cool. I even found some nice CSS nested selector tricks to get help bubble images to appear when I hovered over items; unfortunately, when I tried that code on Internet Explorer, it completely failed to work, so I had to redo it using JavaScript.
(In general, I would be happy if I never had to think about Internet Explorer again. Unfortunately, that’s not realistic for me right now. (At least professionally; when I’m playing around with JavaScript at home, I don’t care!) Fortunately, nine out of ten times, IE 7 and 8 are happy to render my layout in the way I expect; and in three out of the four times when it doesn’t, I can find a workaround that doesn’t look too bad or mess up my code too much. But that last time out of 40 can be a real pain…)
I also want to talk about testing, but I’m already over 900 words, it’s getting late, and I’m at a reasonable stopping point. So I’ll come back to that later in the week.
Post Revisions:
This post has not been revised since publication.
[…] I mentioned earlier, I’ve been having a lot of fun at work playing around with JavaScript and CSS. But there is […]
6/5/2010 @ 9:03 pm