Dragging (and dropping) effectsDragging (and dropping) effects

For Typeturner’s comment submission form I elected to use an ajax submit button. Not just to use ajax—I’m over that affliction—but because it provides a handy solution to the problem of transient (non-bookmarkable) Wicket URLs. If you submit and update by ajax, the location bar retains its pristine reference to the current address.

The downside is that non-ajax browsers (whatever those are) will be unable to post comments. But even on my old Typo-running weblog I’d turned on ajax-only comments just to reduce spam. Most people (and practically everyone you would want to comment) have ajax-capable browsers. Since this trade provides a real benefit to everyone by preserving permanent URLs, I decided to go with it.

[Update: never mind that hand-wringing. I forgot that Wicket’s ruby slippers would have my form working with JavaScript off without me lifting a finger.]

The bumpy part is updating to display the user’s comment. In the layout I’m using (an unconventional but promising one if you ask me) comments appear along the left column starting from the top, so it’s essential to scroll up to show that a comment was added. [Update: not anymore, see note at end.] My first attempt updated the document’s location to the new comment anchor, using JavaScript calls tagged onto the same ajax request. That worked in some browsers, but others were apparently not ready to reference a node immediately after its ajax-creation.

Bringing in the hired help

At that point I thought, maybe I should use some expertly created JavaScript library that will smoothly scroll any element ID into view, work across all browsers in all conditions, and do my laundry.

The first library I considered was Dojo, because its Wicket integration package is “not dead.” In fact you can get a 1.3.0 snapshot-compatible version from the Wicket Stuff repository, which is much more “alive” than Coderspiel is used to.

So that’s all very great, but let me tell you what is not so great: lots of things on Dojo’s site. First of all, there are the words “3.7mb tar.gz” on the download link. This is too big. I don’t care if it comes with Flash and Java integration. I didn’t download from that link since I was using the integration package, but still. 3.7mb compressed?

The second not-so-great thing on their site is its API browser. Don’t click on the link in the preceding sentence unless you are really bored. I’ve never had it render in under thirty seconds, and it doesn’t work at all in Opera Linux. That monstrosity of JavaScript is supposed to show how great their library is, I guess, but it serves instead as a warning against going overboard with client side code. Compared to a traditional alternative like static Javadocs, their showcase API browser is slow, confusing, and unreliable.

Nevertheless I found what I was looking for with it. I would link to the relevant “page”—but that’s not possible! Anyway, Dojo has a function called scrollIntoView that sounds like it would do what I want (though not with any animation). So I tried to use it from the Wicket integration package, but nothing happened other than my page taking longer to load. Turns out, the scroll function is not in the package. (I grepped.) That’s odd, since it’s only one point release behind the one advertised on the site. Who knows when the function was added to the API or even what version of the API is rendered in the API browser, because none of that information is provided. So ended my visit to the Dojo.

jQuery is another, newer, JavaScript toolkit that people talk about. It has a cool, innovative, compact syntax, says everyone. If you go to its front page, you’ll see a snippet of code and a run button. As I clicked on the run button and a hidden paragraph slowly, ostentatiously expanded onto the screen, I had a realization: no one cares about this crap anymore.

Ajax is a huge, Web-changing technology. JavaScript effects are not. The only people ever impressed by them were programmers who recognized their novel use of the browser. For everyone else, bombarded by Flash nonsense all day long and not knowing or caring about the difference, JavaScript effects either go unnoticed or are just another annoying distraction. At this point, as a programmer, I’ve seen enough of the library-driven effects that I don’t care if I ever see one again.

And when I looked for a something in jQuery to help me scroll to a newly-created element, I couldn’t find anything anyway.

Back to the workshop

All I needed were two basic functions: one to get the coordinates of an element, and one to get/set the current top-of-viewport scroll position. I quickly found the former in a findPos(obj) function at Quirksmode. It worked perfectly on all browsers (once it dawned on me to call it from a 50ms timer callback so the DOM could settle in after the ajax update).

I assumed that the scrolling functions would be standard JavaScript, so I googled for them. I’ve since decided that googling for low-rent JavaScript and CSS is a trap. You end up at suspiciously dated sites; they reference Netscape 4 and other things one doesn’t bring up in polite conversation, while cheerfully offering code that isn’t at all cross-platform. After a frustrating hour I’d crafted a function from their detritus that was cross-platform. Then I stumbled on Quirksmode’s page on exactly my problem. Harumph.

To get back at the man, I decided to animate the scrolling the way I’d imagined it should be. Tweening functions are easy and fun to code, as I was reminded in toying in Processing. You just pick an update interval and plot a path with a mathematical function. I decided to move the viewport one quarter of whatever distance remained at each interval, rounding up to whole pixels. So it moves quickly at first and slows down for the kill. Enough talking—recurse!

function scrollToPosition(y) {
	cur = getPosition(); // boring!
	dy = Math.ceil((y - cur) / 4);
	window.scrollBy(0, dy);
	if (cur != getPosition())
		setTimeout(function() { scrollToPosition(y); }, 50);
}

That’s it, no Ph.D. required. You can also browse the scripts: { A, B }.

Ninja turtles laugh at the end of every episode

There are a few things I’m taking away from this exercise. Firstly, don’t be intimidated by fancy shmancy effects. You can write that code in your sleep, and make it do exactly what you want instead of choosing from a library’s cheeky overplayed presets. Bonus: your code will be a thousand times smaller than the library’s—maybe even a million! (Seriously… Dojo.)

And for your own safety, start all future client-side missions at the Quirksmode headquarters. There’s a book too, ppk on JavaScript, but those old school book-things are even harder for me to use than Dojo’s API browser.

Wanna see the scrolling animation in action? You know what to do. Too bad! The comments no longer appear in the left column, because that proved to be annoying for longer comments. So there’s no need for the effect here, and this post is kind of pointless now unless you need to do smooth viewport scrolling for some reason.

Codercomments

Hah… first to see the scrolling in action (using safari for the tasting).

And it works as advertised. Perhaps a bit too fast for my taste, didn’t know what hit me.

Another quirk is that you get the comment aligned at the top of the viewport, with half an article to the right. It might be something to get used to though.

Great article (again). I was starting to miss the longer articles. This one made me smile.

Do I want to see the scrolling?

I tried, and was redirected to this page: […]

Ubuntu 6.10, Firefox 2.0.0.3, Javascript enabled.

Okay, the second try worked. Very wacky.

My session timeout was too short—sorry about that. I think it’s fixed now.

Nice article. :)

Yeah, the quick jump to the top is a bit disconcerting if you aren’t expecting it (and who would be?). Still a neat looking trick, though.

Gosh, I’d better put up an epileptic seizure warning, at least until I get a chance to bump up the callback timer to 75ms. ;)

I do have the session timeout set to one hour now, at the cost of me not being able to edit anything here (because ModalWindow is broken in the current snapshot). A stable Wicket 1.3 beta, whenever it arrives, will be much appreciated in these parts!

where is my scrolling animation? and why didnt you use ajaxfallback button?

Well, test, maybe I’ll do just that! At the moment I’m using the indicating button and I don’t think (?) there’s one with both fallback and indicating built in, though yes I can toss it together myself. I take it one feature at a time, or else I’d never finish anything.

Thanks for the article, n8. It’s always interesting and rewarding to read your stuff. An inspiration for us wanna-be’s out there. :-)

Typeturner looks very promising. Maybe it’s time for me to get rid of that php-based monster I have now…

Oooh, and the scroll function is quite tasty. I’ll buy you a dinner at Nobu next time I’m in NY. :D

Just wanted to see the scroll effect. Nice article, btw. =D

You’re all much too kind. I’ll take heart in your support if Dojo devotees ever show up here and start throwing karate chops, or whatever it is they do.

The other issue with all these JavaScript libraries is what to use if you actually write frameworks for other people to use (like, say, Wicket).

Scriptaculous with Prototype, the Mootools code, Dojo and the Yahoo stuff stomp all over each other. If you use any of them in your component library, woe betide you if your users wish to use another JS library on the same page. You end up just snipping out the bits you need and namespacing them, which is probably how it should be anyway.

It would be nice if we could sort this out properly. We could take mootools, for example, chop it up into much smaller snippets of functionality, and have Wicket decide which bits to dynamically include in the page. You’d serve the JS up as a single <link> to a Wicket resource, with only the code you actually need. To call effects / whatever, you’d write Java code (new Effect.Highlight(Component, TimeUnit.SECONDS, 1) or similar).

Of course, it would be rather a lot of work implementing it in the first place and subsequently keeping it all in sync. :-/

And actually writing Databinder for other people to use, I face the same issue. I was considering adding some integration with jQuery, but now I don’t think it’s worth the trouble whether you’re talking about jQuery or mootools or whatever comes out next. These kits just aren’t that impressive in what they can do (vs. what one could code up oneself) and there will always be Flash (or even Java applets using Processing) if you want to do serious effects.

I must say that I’m starting to like TypeTurner. Great work and keep it up!

Thanks—one of these days I will have to give Typeturner a website of its own to encourage other people to use it. But probably not until its build and setup process is reasonably simple, and it’s based on less than seventy-five percent pre-release dependencies! Not to worry though, typeturner.com is already mine.

Hehe, I know exactly what you mean about Dojo. I seriously thought my browser was broken the first 3 times I (re)opened Dojo’s website. Now let’s see how my comment gets added.

The scrolling :)

Nice site! Just bookmarked, and awayting my return..

What a great way to get extra comments on your site? I hear turtles with swords laughing.

I know! Except it’s not so much extra comments as any comments. I will take what I can get though. Next week: add a comment, get a free copy of the HD-DVD decryption code!

just wanted to see effect…

Add a comment