views:

715

answers:

6

Hey,

I write a lot of dynamically generated content ( developing under PHP ) and I use jQuery to add extra flexibility and functionality to my projects.

Thing is that it's rather hard to add JavaScript in an unobtrusive manner. Here's an example:

You have to generate a random number of DIV elements each with different functionality triggered onClick. I can use the "onclick" attribute on my DIV elements to call a JS function with a parameter but that is just a bad solution. Also I could generate some jQuery code along with each div in my PHP "for" loop, but then again this won't be entirely unobtrusive.

So what's the solution in situations like this?

A: 

This resource may help you with unobtrusive Javascript: http://onlinetools.org/articles/unobtrusivejavascript/

Optimal Solutions
+5  A: 

You need to add something to the divs that defines what type of behaviour they have, then use jQuery to select those divs and add the behaviour. One option is to use the class attribute, although arguably this should be used for presentation rather than behaviour. An alernative would be the rel attribute, but I usually find that you also want to specify different CSS for each behaviour, so class is probably ok in this instance.

So for instance, lets assume you want odd and even behaviour:

<div class="odd">...</div>
<div class="even">...</div>
<div class="odd">...</div>
<div class="even">...</div>

Then in jQuery:

$(document).load(function() {
$('.odd').click(function(el) {
// do stuff
});
$('.even').click(functino(el) {
// dostuff
});
});

jQuery has a very powerful selector engine that can find based on any CSS based selector, and also support some XPath and its own selectors. Get to know them! http://docs.jquery.com/Selectors

roryf
I would strongly urge you to steer away from using the class as the determining factor - even if you do want different "looks" for them, you are still coupling behavior to presentation information.
Jason Bunting
I know what you're saying, so what about the 'rel' attribute then?
roryf
Only in a situation where you attach presentation to the class name. This is easily overcome with extraneous suffixes, such as "odd__" or "even__". The only other option is pointed out below -- use child/parent relationships.
hal10001
A: 

It's a bit hard to tell from your question, but perhaps you can use different jQuery selectors to set up different click behaviours? For example, say you have the following:

<div class="section-1">
    <div></div>
</div>
<div class="section-2">
    <div></div>
</div>

Perhaps you could do the following in jQuery:

$('.section-1 div').onclick(...one set of functionality...);
$('.section-2 div').onclick(...another set of functionality...);

Basically, decide based on context what needs to happen. You could also select all of the divs and test for some parent or child element to determine what functionality they get.

I'd have to know more about the specifics of your situation to give more focused advice, but maybe this will get you started.

Andrew Hedges
I was talking about a general situation not a particular problem. Though something you said caught my attention. I could use the child/parent selectors to obtain functionality in some cases. Thanks
Brayn
A: 

I would recommend disregarding the W3C standards and writing out HTML-properties on the elements that need handlers attached to them:

Note: this will not break the rendering of the page!

<ul>
    <li handler="doAlertOne"></li>
    <li handler="doAlertTwo"></li>
    <li handler="doAlertThree"></li>
</ul>

Declare a few functions:

function doAlertOne() { }
function doAlertTwo() { }
function doAlertThree() { }

And then using jQuery like so:

$("ul li").each(function ()
{
    switch($(this).attr("handler"))
    {
        case "doAlertOne":
            doAlertOne();
            break;

        case ... etc.
    }
});

Be pragmatic.

roosteronacid
A: 

I haven't don't really know about JQuery, but I do know that the DOJO toolkit does make highly unobtrusive Javascript possible.

Take a look at the example here: http://dojocampus.org/explorer/#Dojo_Query_Adding%20Events

The demo dynamically adds events to a purely html table based on classes.

Another example is the behaviour features, described here:http://dojocampus.org/content/2008/03/26/cleaning-your-markup-with-dojobehavior/

Ged Byrne
+2  A: 

I would recommend that you use this thing called "Event delegation". This is how it works.

So, if you want to update an area, say a div, and you want to handle events unobtrusively, you attach an event handler to the div itself. Use any framework you prefer to do this. The event attachment can happen at any time, regardless of if you've updated the div or not.

The event handler attached to this div will receive the event object as one of it's arguments. Using this event object, you can then figure which element triggered the event. You could update the div any number of times: events generated by the children of the div will bubble up to the div where you can catch and handle them.

This also turns out to be a huge performance optimization if you are thinking about attaching multiple handlers to many elements inside the div.

Rakesh Pai