hn-classics/_stories/2005/779690.md

7.4 KiB
Raw Blame History

Source

John Resig - Selectors in Javascript

John Resig]6

John Resig

Selectors in Javascript

Ever since the Behaviour code was released, some time ago, my mind has been churning this powerful topic over. The premise for the module is as follows: Using the power of Pseudo-CSS Selectors, bind your Javascript functions to various HTML elements in the DOM. Looking at how Behaviour works, Ive never been completely happy it simply seems too tedious and verbose for everyday use. Ive since begun to tinker with different styles of code layout trying to find an optimal solution. Some of my biggest gripes with Behaviour are:

  • You cant do any heirarchical selectors. For example, binding to “#foo bar” and “#foo bar .baz” fall under two completely different statements. It seems as if this could/should be streamlined.
  • The Behaviour object doesnt provide any sort of binding-enhancers to make attaching to an event (e.g. “click”) easier to do.
  • The resulting Behaviour code is simply too verbose and too ugly there is an excess of characters/formatting which will probably scare off a casual Javascript programmer.

Ive created a syntactical mock-up for how I think Behaviour couldve been implemented. Im not sure if Im completely happy with it yet the only way to know is to do some real-world testing and come back with some tweaks.

Sample #1

Note: In all of these examples, Behaviour uses element.onclick (or similar bindings) in order to attach an event handler this is generally accepted as an improper way of doing this, since you will only be able to attach one event handler at a time newer handlers will overwrite older ones.

  Behaviour.register({
    '#example li': function(e){
      e.onclick = function(){
        this.parentNode.removeChild(this);
      }
    }
  });

The same as above, done in my code:

  $('#example li').bind('click',function(){
    this.parentNode.removeChild(this);
  });

Syntactic fluff comparision (This is a comparision of how many extra non-critical characters there are, slowing the programmer down not counting endlines/whitespace):

A: Behaviour.register({'':function(e){e.on=}});
B: $('').bind('',);

Sample #2

This is the second example made available on the Behaviour web site. It goes to two disparate branches in the DOM Document and attaches two different event handlers.

  Behaviour.register({
    'b.someclass' : function(e){
      e.onclick = function(){
        alert(this.innerHTML);
      }
    },
    '#someid u' : function(e){
      e.onmouseover = function(){
        this.innerHTML = "BLAH!";
      }
    }
  });

The same as above, done using my syntax:

  $('b.someclass').bind('click',function(){
    alert(this.innerHTML);
  });

  $('#someid u').bind('mouseover',function(){
    this.innerHTML = 'BLAH!';
  });

Syntactic fluff comparision

A: Behaviour.register({'':function(e){e.on=},'':function(e){e.on=}});
B: $('').bind('',);$('').bind('',);

Sample #3

This is the Behaviour code required to meet a more advanced test case. I included changing style properties and element attributes.

  Behaviour.register({
    '#foo ol li': function(a) {
      a.title = "List Items!";
      a.onclick = function(){alert('Hello!');};
    },
    '#foo ol li.tmp': function(a) {
      a.style.color = 'white';
    },
    '#foo ol li.tmp .foo': function(a) {
      a.style.background = 'red';
    }
  });

And the same result using my syntax:

  $('#foo ol li')
    .set('title','List Items!')
    .bind('click',function(){alert('Hello!');})
    .select('.tmp')
      .style('color','white')
      .select('.foo')
        .style('background','red');

Syntactic fluff comparision For this comparision I included the selectors that Behaviour uses, but shouldnt need to.

A: Behaviour.register({'':function(a){a.=;a.on=;},'#foo ol li':function(a){a.style.='';},'#foo ol li.tmp':function(a){a.style.='';}});
B: $('').set('','').bind('',).select('').style('','').select('').style('','');

Im going to have some more information on, how exactly, this new method of binding would work hopefully along with some demoable code. More coming very soon!

Posted: August 22nd, 2005


**Subscribe for email updates**

3 Comments (Show Comments)

  1. **Emmett Shear** (August 22, 2005 at 9:12 am)

Ive been looking at Behavior as well for my AJAX site (going beta in a week or so!), but was turned off for the same reason you were. I have some code which is in effect doing what youre talking about here, but its not so neatly bound with the dom objects. Ill be sure to check back, and Id be glad to help you try and test it if you get something running.

  1. **Bob Aman** (August 22, 2005 at 10:54 am)

Great stuff John. Thanks for doing this. I was using Behavior too, and yeah… wasnt a fan of those things either, especially since Im trying to serve up application/xhtml+xml and I ran into lots of problems with Behavior in that setting. So I stopped working with Behavior and went back to the old way of doing things because I was too lazy to fix it.

  1. **Ben Darlow** (October 5, 2005 at 5:42 am)

Very good points. I myself only recently discovered and played with Behaviours, but was disappointed by the limited support for CSS selectors (in particular, attribute selectors). A better implementation would be very welcome!


Comments are closed.
Comments are automatically turned off two weeks after the original post. If you have a question concerning the content of this post, please feel free to contact me.


Secrets of the JavaScript Ninja

Secrets of the JS Ninja

Secret techniques of top JavaScript programmers. Published by Manning.

Subscribe for email updates

John Resig Twitter Updates

@jeresig

Infrequent, short, updates and links.