Using jQuery for DOM event attributes

My last post discussed my conversion to JavaScript frameworks, and why you should be one too. I explained that I settled on jQuery because it simplified how I write JavaScript without strictly locking me into a set of features and effects. A core part of this flexibility comes from jQuery’s document ready wrapper. It works like window.onload(), but provides a quantum leap in functionality. You can find more details at the link. Suffice it to say that all jQuery event listeners must go inside a document ready wrapper. The problem is that document ready listeners only apply to DOM elements that exist when the document is ready. It works like a snapshot. When the document is finished loading, jQuery takes a picture of how it looks and references it for activating listeners. “So what’s the problem?” you might ask. Anything that exists in DOM after that picture is taken essentially does not exist for listening purposes. Let’s look at an example. First, here’s a simple block of HTML:lang="html">

generate new html

...and the accompanying jQuery magic:
<pre lang="javascript">
$(document).ready(function(){

  $("a.currentAction").click(function(){

    $("span#fooBar").append(

      '

<a href="#" class="newAction">new action link</a>'

    );

  });

  $("a.newAction").click(function(){

    alert('Here I am!');

  });

});

The link inside the span will create a new link using jQuery. That new dynamic link has its own jQuery listener to create a second new link as well. The catch is that the second link will never work; you’ll never see that alert box listed in line 8. The jQuery DOM doesn’t have an awareness of the second link at load time, so for its purposes the link doesn’t exist. Don’t believe me? Check out the demo I put together. I’ll wait. Weird, right? Not to mention annoying… So how can we daisy chain page dynamics using jQuery? Simple, we just have to go old school. Since jquery can’t listen to something that doesn’t exist at load time, we have to create a new listener. The easiest way to do that is using the onclick event. Let’s modify the JavaScript code from above a bit…lang="javascript"> $(document).ready(function(){

$("a.currentAction").click(function(){

$("span#fooBar").append(

  '

new action link

);

});

}); function newClickAction(object) {

$(object).css({ backgroundColor:“yellow”, fontWeight:“bolder” });

alert(‘Here I am!’);

}

This time, the new action stands on its own as a separate function, outside the `document ready` wrapper. We then added an onclick event to the generated HTML, thereby creating a new listener for the new link.  The alert box will appear this time, and here's <a href="/examples/jquery-dom-event-2.html">another demo to show it in action</a>.
There are two other things to note about this second example. First, notice that we have used jQuery code inside our custom function. The magic jQuery function `$()` is defined in the pages global scope.  Since jQuery still must operate within the normal parameters of JavaScript, that function is available inside any other function. The thing to note here is that **you can use jQuery outside of the document ready wrapper**. This rule applies to any JavaScript library you might use.
The second thing to note in our second example is the argument called "object" passed into `newClickAction()`. This variable refers to the magic JavaScript variable `this`, which we placed inside our jQuery-generated HTML.  The variable `this` always refers to the object in which it is called, whether it be a function or page element. jQuery is aware of the contents of a this reference, and thus can immediately identify the element by making it the sole argument of the `$()` function, as opposed to getting the element by id, class names, or tree navigation (i.e. parent descendant).
The two additional concepts are put into action when you click the link. jQuery finds the element and changes the background highlighting, while showing the alert box at the same time.
As you can see, things get pretty dicey quickly with uber-powered AJAX pages. Just make sure to keep your code clean, work on a single feature at a time, and you should be fine.