Forum Moderators: open

Message Too Old, No Replies

Move JavaScript events to JavaScript includes?

Making JavaScript unobtrusive and getting ready to use two DHTML engines...

         

JAB Creations

3:16 pm on Apr 13, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



First I implemented script.aculo.us and only about two or three days ago I then replaced it with jQuery. My results were mixed as one engine would work in a browser that the other would not, and sometimes they would both work in a browser. Since I'm going for maximum compatibility I've decided to take a crack at modularizing both DHTML libraries and moving their scripts to be located exclusively in the include files. One for the DHTML engine, one for the page functions. If I can get that to work then giving the user (or the system) the ability to switch or specifically choose an engine will be a piece of cake!

I've got two basic examples, one from script.aculo.us and the other from jQuery. All I want to do is move these events out of the XHTML and in to their own JavaScript includes file. All necessary elements that trigger or display DHTML events have id attributes with unique values.

jQuery - H1 Element (id="h1")

<h1 onclick="$('#div01').BlindToggleVertically(1000, null, 'bounceout');return false;">

script.aculo.us - H2 Element (id="whats_new")

<h2 onclick="new Effect.toggle($('div02'),'blind');">

To keep my code as clean as possible I know I need to detect if the element/id exists though I'm not sure if this is the correct way to detect an element by it's ID...

if (getElementsByTagName("header1"))

I tried the following but it's not working of course. ;)

document.header1.onclick = $('#div01').BlindToggleVertically(1000, null, 'bounceout');

- John

Little_G

3:48 pm on Apr 13, 2007 (gmt 0)

10+ Year Member



Hi,

I'm not sure if this is the correct way to detect an element by it's ID...
...it's not, you should use:
if(document.getElementById("header1"))
assuming that the element you are looking for has an id of 'header1'.
In terms of attaching event handlers, I don't know exactly how jQuery works but I'd try something like:
document.getElementById('header1').onclick = $('#div01').BlindToggleVertically(1000, null, 'bounceout');

ps. If I don't do it then someone will come along and say that you shouldn't assign functions to the onclick "attribute" anymore and instead use DOM functions [developer.mozilla.org] but that's up to you.

Andrew

[edited by: Little_G at 3:50 pm (utc) on April 13, 2007]

Fotiman

4:23 pm on Apr 13, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month




All I want to do is move these events out of the XHTML and in to their own JavaScript includes file.

So you're looking to attach your event handlers in an unobtrusive way... excellent.

Well, considering you're already including 2 JavaScript Framework/Libraries, you probably don't want to add a third. However, the Yahoo UI Library works especially well with event handling. Here's how you might do it with the Yahoo UI Library's Event Utility:


// Attach the event handlers when the page loads
YAHOO.util.Event.on(window,'load',function(e){
// Attach the onclick event listener to header1
YAHOO.util.Event.on('header1','click',function(e){
$('#div01').BlindToggleVertically(1000, null, 'bounceout');
// Stop the click event if you need to
YAHOO.util.Event.stopEvent(e);
});
// Attach the other event listener
YAHOO.util.Event.on('header2','click',function(e){
new Effect.toggle($('div02'),'blind');"
});
});

In that example, it will attach the event handler to the element with id 'header1' if it exists. If it does not exist, then it doesn't cause an error (that is, you don't have to explicitly check for 'header1' because this method does that for you).

Your markup would then need to look something like this:

<h1 id='header1'>...</h1>
<h2 id='header2'>...</h2>

Anyway, like I said, you're already including two other libraries, so including a third might be overkill. But I thought I'd mention it just in case.

whoisgregg

8:38 pm on Apr 13, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Scriptaculous is built on top of Prototype, so he's already up to three libraries. ;)

The Prototype manual page for Event.observe [prototypejs.org] should shed light on how to attach an onclick event using Prototype.

JAB Creations

9:10 pm on Apr 13, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks for both replies, Little_G I get the following error in the JavaScript console...

Error: document.getElementById("header1") has no properties.

I know there are many DHTML libraries but it won't matter how many there are unless I can figure out how to get the code working in a way that I can replicate and hopefully also figure out how to apply to other DHTML engines.

This to me should work but is not...

if(document.getElementById("header1")) {alert ("This is a Javascript
Alert")}

Thanks for the replies thus far...
- John

Fotiman

9:33 pm on Apr 13, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Do you have an element on your page that has an id of header1?

JAB Creations

10:49 pm on Apr 13, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



In my original post I forgot to add ids to the to the headers, my bad. We can reference them as header1 and header2.

- John

JAB Creations

12:50 am on Apr 14, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



THIS WORKS!

function init() {
$("#header1").click(function(){
$("#div01").BlindToggleVertically(1000,null, 'bounceout');
return false;})
}
window.onload = init;

*dances*

- John

whoisgregg

3:52 pm on Apr 15, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Glad you got it sorted!

As I understand it, the more Prototype-ish way of handling events looks like this:

Event.observe(window, 'load', function() {
Event.observe('header1', 'click', function(event){
$("div01").BlindToggleVertically(1000, null, 'bounceout');
Event.stop(event);
});
});

The main difference being that using Event.observe registers additional handlers to the events whereas using DOM level 0 event properties (like

window.onload
) will incapacitate any other handlers. So, instead of forcing all your event handlers into one centralized
init()
function, you can actually attach event handlers where it makes sense for those handlers to exist in your code.

Just something to chew over, ultimately it's a matter of choice and style for each programmer. :)

Dabrowski

3:24 pm on Apr 16, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I often have 6 or 7 separate JS files included.

I always (well, unless something prevents it) write completely self contained scripts that attach themselves where necessary. I find Scott Andrews' addEvent function extremely useful:

function addEvent(elm, evType, fn, useCapture)
{
//Credit: Function written by Scott Andrews
//(slightly modified)

var ret = 0;

if (elm.addEventListener)
ret = elm.addEventListener(evType, fn, useCapture);
else if (elm.attachEvent)
ret = elm.attachEvent('on' + evType, fn);
elseelm['on' + evType] = fn;

return ret;
}

addEvent( window, "load", doMyFunction);

This is also an additive function, as multiple addEvent calls won't overwrite previous functions.