views:

70

answers:

3

I have read quite a bit about unobtrusive JS and how to generate it and all that jazz...

My problem is this: I have a website that heavily relies on mod_rewrite, so essentially all the pages requests are sent to index.php that generates the main structure of the page and then includes the appropriate page. Now, there are different sections in the site and each section uses different Javascript functions (e.g. for different AJAX requests).

Now, if I just were to attach a function to the onload of the page obviously the thing would not work, as I do not have to initialise the same things for each page... so what is the best way to handle this situation?

I hope the situation is clear, I'll be happy to clarify if needed

+3  A: 

You can use addEventListener (standard) or attachEvent in the HTML generated by the subsidiary PHP pages.

The syntax is simple. E.g.

document.addEventListener("load", someFunction, false);

This allows you to generate the full body tag in index.php but run different load handlers for each page. Also note that you can use this multiple times on the same element.

Matthew Flaschen
So essentially I would have an `addEventListener` call in each of the PHP pages and then several functions that do different things depending on the page, right?
nico
Yes. If it's more convenient, you can have multiple `addEventListener` calls.
Matthew Flaschen
+1  A: 

Nico, I would suggest creating a custom javascript code with each included page (doesn't matter where on the page you include the script tag) and, as Matthew suggested, after you define a function to run on page load, use the addEventListener to load that custom function on "load"
Let's say you define a function pageinit() somewhere in the body of the included document

function pageinit(){..
}
window.addEventListener("load", function() { pageinit(); }, false); 

Does that make sense for your project?

Raine
Yes it does make sense, I had something like that in mind, just wanted to see if there were any other options available before starting to change all the code :)
nico
you may define each separate JS function for each included page, so that you don't load the others you won't use, but you may also bundle them all up and include as an external js file in the head section of your index.php and then just call addEventListener with the appropriate function name in each included page
Raine
there are, of course, other options, but not as efficient as the one discussed here.
Raine
+1  A: 

I would simply put it in a .js file.

mysite_common.js - site wide common utils and functions

mysite_page_a.js - unique functionality for page a

mysite_page_b.js - unique functionality for page b

for page b you include b.js while on page a you would include a.js

Then in your respective unique.js you can wrap your functionality in a ondomready or similar.

Keep it separate from your PHP, then it is much less of an annoyance later, it also means that you can rely on caching for your js to keep your page loads slimmer.

You can also look at things like YUI loader which allows you to do much more complex things like ondemand loading of bits of js functionality.

You can use event delegation to provide different functionality depending on context.

Basically it works by attaching an event listener to a container element which captures clicks on child elements. You can then do away with individual event listeners alltogether, as well as look at hints from the parent. say:

<div id='container' class='page_a'>
...
    <input name='somename'>
...
</div>

Then

var attachDelegates = function(container){
    container.onclick = function(e) {
    e = e || window.event;
    var t = e.target || e.srcElement;

    //Your logic follows
    if(t.name === 'somename'){
         dosomething(t);
    }
    if(t.className === 'someclass'){
         ... something else ...
    }
};

and onload = function(){attachDelegates('container');};

The attachDelegates function could be different for each page, or you could have a monolithic one and simple attach hints to the container or be selective about which classes you attach.

These are much more coherent explanations and examples:
http://cherny.com/webdev/70/javascript-event-delegation-and-event-hanlders
http://blog.andyhume.net/event-delegation-without-javascript-library

Personally I use YUI3 http://developer.yahoo.com/yui/3/examples/node/node-evt-delegation.html

as it gives me CSS3 style selectors and is pretty hassle free so far.

unomi
Well, I already have separated JS files as you suggested, so that's already done.The thing I would like to change is "simply" that right now the events are defined inline (e.g. <input onclick="dosomething()" />) rather then being attached when the page is loaded.
nico
Then it sounds like you are asking the wrong question :)Have a look at `event delegation` fx: http://blog.andyhume.net/event-delegation-without-javascript-libraryor http://developer.yahoo.com/yui/3/examples/node/node-evt-delegation.html then you won't necessarily have to care which page you are loading, you target your actions using css classes.
unomi
@unomi: thank you for the reply. I understand your point about delegation, I'm trying to decide which one would be the more lightweight solution. Anyway thanks to everyone for the answers, is good to see different ways to do the same thing.
nico
Well, event delegation is basically _the_ solution for lightweight unobtrusive javascript. I think you will find that your initial phrasing did not capture what you actually seemed to be looking for, the other answers, and my initial one, were about how to initialize different logic for different pages, not about how to hook up the logic to the HTML.
unomi