faded picture of luke
a semi-random photo | click for the full photo gallery
click to browse photos
homepage navigation

Luke Melia

5 Tips for porting javascript from Prototype to jQuery

I’ve been really enjoying working with jQuery and the pattern of progressive enhancement.

But I haven’t been enjoying supporting both Prototype/script.aculo.us and jQuery on in the same web app. It felt downright wrong to make my visitors download all that javascript.

So, this weekend, I set out to eliminate the last of the public-facing prototype-dependent code from weplay and gained some peace of mind along with a 50% reduction in javascript bytes required for the fattest page.

Here are a few tips based on my experience so far:

  1. Grab your inheritance. For porting components that rely on Prototype’s Class.create mechanism, the most straightforward path is to leverage a jQuery-native implementation of the same concept. I used Dan Webb’s $.klass code from his jQuery version of LowPro. I also came across the jquery-klass project, which looks like it would do the job.

    It feels a little dirty to bring Prototype’s inheritance-based OO approach into jQuery — the jQuery philosophy is more about embracing the prototype-based OO baked into the language. As part of a porting effort, though, I think this approach makes sense, at least for a step.

  2. Firebug is your friend. After I addressed the Class.create challenge, my approach was basically to repeatedly load the page in the Firefox and fix the first error that Firebug reported. By the time I worked through them all, dealing with a few remaining IE-specific issues was not too bad.
  3. Enjoy watching the code shrink. Here’s a bit of code before and after the port…

    Before:

    this._arrow = document.createElement('img');
    this._arrow.border = 0;
    this._arrow.className = 'color_picker_arrow';
    this._arrow.src = this.settings.arrowImage;
    this._arrow.margin = 0;
    this._arrow.padding = 0;
    this._arrow.style.position = 'absolute';
    this._arrow.style.top = '0px';
    this._arrow.style.left = '0px';
    this._arrow.style.zIndex = 10000;
    document.body.appendChild(this._arrow);
    

    After:

    this._arrow = jQuery(document.createElement('img'))
    .attr({border: 0, src: this.settings.arrowImage})
    .addClass('color_picker_arrow')
    .css({margin:0, padding:0, position:'absolute', top:0, left:0, zIndex:10000})
    .appendTo(document.body);
    
  4. Grok the jQuery event model. jQuery has excellent support for working with events, but it is different from Prototype’s. In particular, Prototype’s bindAsEventListener method, which changes what this refers to in your event handler, is nowhere to be found. Figure out how to use closure to attain the same thing and revel in jQuery’s simpler approach to “this”.
  5. Consider jRails. If you’re working in Rails and using the link_to_remote methods, consider jRails as a stop-gap measure to help you show Prototype the door. I say “stop-gap” because link_to_remote does not produce unobtrusive javascript and does not tend to support real progressive enhancement.
  6. Bonus Tip: Learn to write jQuery plugins. While not strictly required by my porting efforts, I wrote a few plugins along the way to help out. Writing a plugin sounds like it could be a big deal, but writing a jQuery plugin is very straightforward, and it’s an addictive way to package up functionality as well as get more comfortable with the jQuery philosophy.

Good luck, and share your porting stories!

LukeMelia.com created 1999. ··· Luke Melia created 1976. ··· Live With Passion!
Luke Melia on software development freelance web development how to contact me Luke Melia, Software Developer letters and more from my travels photo gallery personal philosophy