Luke Melia

software dev

May 18, 2008

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!

11 Responses to “5 Tips for porting javascript from Prototype to jQuery”

  1. Rachel chimed in:

    Nice article!

    I am struggling with converting a script over to jquery from prototype, i cannot understand what should be done with classes.

    The code starts with:

    var chatChannel = Class.create();
    chatChannel.prototype = {
    initialize: function(channel) {

    The script is on: http://www.chabotc.com/javascript/webchat-20-first-release/ (not sure why you’d need that but just in case!).

    Any help would be massively appreciated!

  2. Jake Rutter chimed in:

    Luke,
    At FanBoom, we are moving from prototype to jQuery too! jQuery is just much lighter and easier to use than the clunky prototype. Nice post, its very helpful. Will bookmark this!

  3. Esekla chimed in:

    A lot of work with javascript here, but keep in mind that some (many?) of us end users expect (demand?) web pages to function simply as documents. Furthermore, much of what’s done with javascript can be accomplished with plain dhtml, avoiding processing and security glitches.

    The single most popular add-on for Firefox is NoScript.

  4. Luke Melia chimed in:

    @Esekla — I hear what you’re saying. I’m a big proponent of progressive enhancement, which means that a website functions fine without javascript, and functions even better when javascript is available.

    The stats are that 95% of web users have javascript enabled.

    One note: “DHTML” includes the use of javascript — perhaps you meant much of what’s done with Javascript can be accomplished with HTML + CSS, in which case I agree, and that’s certainly my first choice when it’s available. But there is a ton of fun, useful features that Javascript makes possible, and offering 95% of your users an easier, more enjoyable experience is a great reason to employ a javascript framework like jQuery.

  5. Sebastian Deutsch chimed in:

    Nice article. I’ve also written one about migrating from prototype to jquery – maybe you want to check it out:

    http://blog.9elements.com/?p=12

  6. justin blecher chimed in:

    i know you’re not looking for help with Prototype as you’re switching to jQuery, but it is slightly misleading to show the ‘before’ as Prototype code — it wasn’t using Prototype at all. FWIW, here’s how you could’ve written it using Prototype 1.6:

    this._arrow = new Element(‘img’, { ‘src’ : this.settings.arrowImage, ‘class’ : ‘color_picker_arrow’ });
    this._arrow.setStyle({ ‘border’ : 0, ‘margin’ : 0, ‘padding’ : 0, ‘position’ : ‘absolute’, ‘top’ : 0, ‘left’ : 0, ‘zIndex’ : 10000 });
    document.body.appendChild(this._arrow);

  7. everyone guess what chimed in:

    everyone guess what
    the author of this article basically doesn’t know what he is talking about
    his examples are regular JS and not prototype
    also he misunderstands that unlike jquery, in prototype you can still opt to use the actual language based methods, unlike jQ which has recoded the same functionality that is in js /the jquery way/ whatever that means.

    Don’t ever forget, you use jQ because you are too lame to be bothered to learn how to actually code, not because jQ is in some way a “better” framework.

  8. lukemelia chimed in:

    @justin: I think that’s a good point. Thanks for sharing the example code.

    @troll: you make the same point as justin made months ago, but manage to do it an obnoxious, disrespectful way with no code examples. Guess that’s why you didn’t leave your real name…

  9. Shared Tutorials » Blog Archive » 5 Tips for porting javascript from Prototype to jQuery chimed in:

    […] Tips for porting javascript from Prototype to […]

  10. javascripter chimed in:

    Sometime pure javascript is enough to implement classes in DOM leaving aside jQuery tricks.

  11. drow chimed in:

    dunno. it sure seems from your overview like abandonning jquery and going full-prototype would’ve been as easy, with similar results.

Leave a Reply

LukeMelia.com created 1999. ··· Luke Melia created 1976. ··· Live With Passion!