Dr Nic

Prototype: “element-id”.$() instead of $(‘element-id’)

The Prototype library gives us the $() operation for converting a DOM element id into the DOM element: $('element-id'). It also appends a bunch of functions to the resulting object; as shown previously, you can add your own methods.

Sometimes though, passing a string into the $() function doesn’t read well; and only makes Javascript code harder to read. For example: $(window.button_list()[3]).hide()

Instead, it’d be nice to have normal chainability. I like the following syntax: window.button_list()[3].$().hide().

That is, call the $() method on a string object, instead of passing the string into the $() method.

Add this code into your application:

String.prototype.$ = function() {
  return $(document.getElementById(this));
}

UPDATE: After discussion on Ruby on Rails: Spinoffs forum

Alternate version:

String.prototype.$ = function() {
  return $(String(this));
}

But what doesn’t work is:

String.prototype.$ = function() {
  return $(this);
}

Let us know if you know why $(this) returns an array of single character strings (e.g. ["e","l","e","m","e","n","t","-","i","d"] for "element-id".$()?!

Related posts:

  1. Autotesting Javascript in Rails I used to love Javascript so much that it would...
  2. Supporting JSON callbacks in Rails Now you know how to write JavaScript widgets, now you...
  3. DIY widgets – How to embed your site on another site UPDATE: Demo and tutorial fixed for IE7. UPDATE: Opera-supporting code....
  4. Extend Prototype $() yourself If you’re using the prototype javascript library, its fun to...
  5. Extending _why’s Creature class Many Rubist’s first explanation of metaprogramming is by why the...

2 Responses to “Prototype: “element-id”.$() instead of $(‘element-id’)”

  1. Andrew Revinsky says:

    Hi everyone!

    The “this” in your latter example refers to an inner implementation of a string in a String object.

    In IE, the “this” is of “object” type, not “string”. The logic of $() function, as you know, first checks whether the argument is a string (by typeof’ing it) and if not, it returns this same object assuming (in our case, wrongly) it’s a DOM element.

    Now, in IE, it turns out, an inner string is still a string in essence (when viewed in debugger it isn’t split unto characters or anything..). But in FireFox although “this” is still of “object” type, it also supports indexing (as seen by Firebug), giving access to individual constituent characters of the string.

    Back to what you had, since String.prototype.$ (and “this” not being a strictly of “string” type) at the end returns the inner String’s object, its output depents on inner String’s object implementation in browsers.

    Dr. Nic, you probably used FireFox for your tests.

    Thank you!

  2. Dr Nic says:

    Yeah, I’m glad I was using Firefox so I could see the error. On the Spin-off forum I think they said they might patch the original $() code so that it does more thorough testing of the arguments.

    e.g argument instanceof String || argument.constructor(String)

    Then the method in the article should just be able to call $(this) in Firefox as well.