I hope I’m not dating myself too much here… I am used to using jQuery’s .live() function whenever I needed an action performed on an element that wasn’t initially in the DOM.

Say for example, I have a page and on that page is a button that loads a modal window (you get a pop-up box and the rest of the screen greys out). The content of the modal window is new (ajax loaded from the server) and it has a button to (for example) save, exit, OK, etc. I would use .live() in that scenario so that the jQuery action associated with the newly formed button would run.

Well, I needed that bit of functionality yesterday and went to pull up the documentation to refresh my memory on it’s usage. And lo and behold it’s been deprecated! Not only is there a newer function (as of 1.4.3+) to use instead ( .delegate() ), but there’s a newer update (as of 1.7+) to *that* which is called .on(). Damn it. Sometimes this stuff moves just too fast.

Anyway, I read up on it a little (not much to read out there) and I tried to implement it. I got caught up on a snag and figured I’d mention to see if I am the only dunce, or if I found something moderately intriguing. I figure the former, but hope for the latter.

Here is a sample of the code I was trying to run:

<div class='linkholder'>
     <a href='somepage.php' class='jquerydosomething' id='12345'>click me</a>
</div>

My jquery code looked like this:

function dosomething (event) {
      alert('ID is '+event.data.id);
      alert('Action is '+event.data.action);
}
$('a.jquerydosomething').on("click", { id: $(this).id, action: makewidget }, dosomething);

Simple right? Wrong. The variable “action” which I had manually typed in got passed along to the dosomething function nicely and worked as expected. However the id, which I wanted to pass along dynamically, did not work as expected. I was assuming (incorrectly) that “this” would refer to the anchor tag. I tried:

  • using $this.id and this.id instead
  • placing the calls to $(this) or $this or this inside the dosomething function instead of passing it as a variable

all trying to get to the reference to the anchor. I don’t know exactly what was passed, but debugging through Firebug showed a lot of gibberish that looked like the entire DOM of the page.

So how did I fix it?

Well I changed the line with .on() to the following and moved the calls to “this” inside my dosomething function in the form of this.id:

$('.linkholder').on("click", ".jquerydosomething", { id: $(this).id, action: makewidget }, dosomething);

So if I were to make an educated guess about what’s going on here… and really I would say it’s more just a “guess” period. It seems as though the .on() function has a reference to all the objects on the left of the dot as “this” (in this case, it would be all references to anything with a class of “.linkholder”). UNLESS you have a selector specified in the set of parameters (.jquerydosomething in this case) which it will then return the the object(s?) with matching selectors that have the triggered event (“click” in this case).

I suppose my question would be aren’t those two rather redundant? I would imagine the way I wrote it the first time it would only return the object that matched the selector (“a.jquerydosomething”) that had the triggered event. I suppose I could just write $.on(“click”, “.jquerydosomething”, dosomething) but I wonder if having the initial selector (.linkholder in this case, but I could just as easily use the “a” tag… maybe) gives a performance boost since the internal selector doesn’t have to scour the entire DOM looking for a match.

If anyone has any insight on what I may be missing, or indeed, the proper terminology when referencing the selectors (inside function vs outside/left of the dot) I’d greatly appreciate it. While I’ve got it working the way I want, improvement is always welcome.