How do you implement a generic Event Handling function


O

Owen Brunker

Below is my MouseOvers Class which is now working fine. It currently
implements the event handler by specifying the handler functions in the
attributes of the HTML Element. I suppose you would call it inline but I am
not sure this is the correct terminolgy.

I have tried to implement the event handlers by assigning them to the
element from within the addItem method without success. The problem is how
to determine which anchor fired the event handler and thus identify the
images to be swapped. The object 'this' doesn't seem to be in context when
the event handler is called. Obviously I would have to pass the id of the
anchor element to the object method addItem() as well as the id of the image
for it to work. In the version below, only the id of the image is passed.
Further down the page is the broken version of what I am trying.

Thanks in advance

Owen Brunker


=== CODE START Working Version ===================
// Included as part of the header of the HTML page.

function MouseOvers() {
this.ImagesIn = new Array();
this.ImagesOut = new Array();
this.addItem = addItem;
this.eventMouseOver = eventMouseOver;
this.eventMouseOut = eventMouseOut;
}

function addItem(idImg, ImageSrcIn, ImageSrcOut) {
var element;
this.ImagesIn[idImg] = ImageSrcIn;
this.ImagesOut[idImg] = ImageSrcOut;
}

function eventMouseOver(idImg) {
var element;
element = document.getElementById(idImg);
element.src = this.ImagesIn[idImg];
}

function eventMouseOut(idImg) {
var element;
element = document.getElementById(idImg);
element.src = this.ImagesOut[idImg];
}


// This function is called from the HTML body and implements the MouseOvers
class
function WritePage() {
document.MouseOverEvents = new MouseOvers();

document.write('<table width="100%" cellpadding="0" cellspacing="0"><tr>');
document.write('<td>');
document.write('<a href="anotherpage.html"
onmouseover="document.MouseOverEvents.eventMouseOver(\'img1\')"
onmouseout="document.MouseOverEvents.eventMouseOut(\'img1\')" title="Does
Something"><img id="img1" src="images/imagein.png"></a>');
document.MouseOverEvents.addItem('img1', 'images/imageover.png',
'images/imagein.png');
document.write('</td>');
document.write('</tr></table>');
}

=== CODE END ===================================



The object below is implemented in the same way the above object is
implemented. The only differences are that the id of the anchor element is
passed as well. Also the HTML is not supposed to need to worry about inline
event handlers.

=== CODE START Broken Version ==================
function EventHandlers(idAnchor, idImg, ImageSrcIn, ImageSrcOut) {
var element;

this.id = idImg;
this.ImagesIn = ImageSrcIn;
this.ImagesOut = ImageSrcOut;
this.eventMouseOver = eventMouseOver;
this.eventMouseOut = eventMouseOut;

element = document.getElementById(idAnchor);
if (element != null) {
element.onmouseover = this.eventMouseOver;
element.onmouseout = this.eventMouseOut;
}
}

function MouseOvers() {
this.EvtMgr = new Array();
this.addItem = addItem;
}

function addItem(idAnchor, idImg, ImageSrcIn, ImageSrcOut) {
this.EvtMgr['id'] = new EventHandlers(idAnchor, idImg, ImageSrcIn,
ImageSrcOut);
}

function eventMouseOver() {
var element;
element = document.getElementById(this.id);
element.src = this.ImagesIn;
}

function eventMouseOut() {
var element;
element = document.getElementById(this.id);
element.src = this.ImagesOut;
}

=== CODE END ===================================
 
Ad

Advertisements

D

David Mark

Below is my MouseOvers Class which is now working fine. It currently
implements the event handler by specifying the handler functions in the
attributes of the HTML Element. I suppose you would call it inline but I am
not sure this is the correct terminolgy.

Inline is correct and it is generally frowned upon as a maintenance
headache.
I have tried to implement the event handlers by assigning them to the
element from within the addItem method without success. The problem is how
to determine which anchor fired the event handler and thus identify the
images to be swapped. The object 'this' doesn't seem to be in context when
the event handler is called. Obviously I would have to pass the id of the
anchor element to the object method addItem() as well as the id of the image
for it to work. In the version below, only the id of the image is passed.
Further down the page is the broken version of what I am trying.

Thanks in advance

Owen Brunker

=== CODE START Working Version ===================
// Included as part of the header of the HTML page.

function MouseOvers() {
this.ImagesIn = new Array();
this.ImagesOut = new Array();
this.addItem = addItem;
this.eventMouseOver = eventMouseOver;
this.eventMouseOut = eventMouseOut;

}

function addItem(idImg, ImageSrcIn, ImageSrcOut) {
var element;
this.ImagesIn[idImg] = ImageSrcIn;
this.ImagesOut[idImg] = ImageSrcOut;

}

function eventMouseOver(idImg) {
var element;
element = document.getElementById(idImg);
element.src = this.ImagesIn[idImg];

}

function eventMouseOut(idImg) {
var element;
element = document.getElementById(idImg);
element.src = this.ImagesOut[idImg];

}

// This function is called from the HTML body and implements the MouseOvers
class
function WritePage() {
document.MouseOverEvents = new MouseOvers();

document.write('<table width="100%" cellpadding="0" cellspacing="0"><tr>');
document.write('<td>');
document.write('<a href="anotherpage.html"
onmouseover="document.MouseOverEvents.eventMouseOver(\'img1\')"
onmouseout="document.MouseOverEvents.eventMouseOut(\'img1\')" title="Does
Something"><img id="img1" src="images/imagein.png"></a>');
document.MouseOverEvents.addItem('img1', 'images/imageover.png',
'images/imagein.png');
document.write('</td>');
document.write('</tr></table>');

}

=== CODE END ===================================

The object below is implemented in the same way the above object is
implemented. The only differences are that the id of the anchor element is
passed as well. Also the HTML is not supposed to need to worry about inline
event handlers.

=== CODE START Broken Version ==================
function EventHandlers(idAnchor, idImg, ImageSrcIn, ImageSrcOut) {
var element;

this.id = idImg;
this.ImagesIn = ImageSrcIn;
this.ImagesOut = ImageSrcOut;
this.eventMouseOver = eventMouseOver;
this.eventMouseOut = eventMouseOut;

element = document.getElementById(idAnchor);
if (element != null) {
element.onmouseover = this.eventMouseOver;
element.onmouseout = this.eventMouseOut;
}

}

function MouseOvers() {
this.EvtMgr = new Array();
this.addItem = addItem;

}

function addItem(idAnchor, idImg, ImageSrcIn, ImageSrcOut) {
this.EvtMgr['id'] = new EventHandlers(idAnchor, idImg, ImageSrcIn,
ImageSrcOut);

}

function eventMouseOver() {
var element;
element = document.getElementById(this.id);
element.src = this.ImagesIn;

}

function eventMouseOut() {
var element;
element = document.getElementById(this.id);
element.src = this.ImagesOut;

"this" refers to your object, not the associated element.
}

=== CODE END ===================================

See the "Example 2: Associating Functions with Object Instance
Methods"

http://www.jibbering.com/faq/faq_notes/closures.html
 
R

RobG

Owen said:
Below is my MouseOvers Class which is now working fine. It currently
implements the event handler by specifying the handler functions in the
attributes of the HTML Element. I suppose you would call it inline but I am
not sure this is the correct terminolgy.

You can add inline event handlers on the server using pretty much
exactly the same logic as you are using to add them on the client.

But anyhow, I'd suggest a scheme where you create a single imageData
object using the element ID as the property name, then onmouseover/out
you can use something like:

var imageData = {
idA: { over: 'aOver.jpg', out: 'aOver.jpg'},
idB: { over: 'bOver.jpg', out: 'bOver.jpg'},
...
}

function mOver(){
this.src = imageData[this.id][over]
}

function mOut(){
this.src = imageData[this.id][out]
}


And dump all the document.write stuff.
 
O

Owen Brunker

RobG said:
You can add inline event handlers on the server using pretty much exactly
the same logic as you are using to add them on the client.

But anyhow, I'd suggest a scheme where you create a single imageData
object using the element ID as the property name, then onmouseover/out you
can use something like:

var imageData = {
idA: { over: 'aOver.jpg', out: 'aOver.jpg'},
idB: { over: 'bOver.jpg', out: 'bOver.jpg'},
...
}

function mOver(){
this.src = imageData[this.id][over]
}

function mOut(){
this.src = imageData[this.id][out]
}

Thanks Rob. I'll experiment with it and see.
And dump all the document.write stuff.

In the long run I want to experiment with providing a page frame work or
skeliton on the server side and having Javascript as plugins provide the
flesh. I would like to see the Javascript itself generated on the fly
server side based on plugin templates selectable from database parameters.
At the end of the day, there is stuff that only the browser knows about.
Either this information is passed to the server so it can be incorporated
into the next page served, or the alternative is that the skeliton is served
along with the javascripted objects and interface code. The resultant page
is built client side. This is a long term thing that involves interfacing
to desktop office management applications I already have in production.

At the moment it is all play to see how far I can push stuff. But first
there is the learning curve.

Cheers
Owen Brunker
 
O

Owen Brunker

That function to associate DOM events with objects has got to be the most
useful three lines of JS I ever dug up. I never could encapsulate my
widgets properly until I found that. But be forewarned that it is also a
prime example of how to introduce memory leaks in IE. There really should
be a bold-faced warning next it to it that links to the section on leaks
found elsewhere in the document. Fortunately the workaround is simple.
Detach the associated listeners in the onunload event of the document.

Yes, I read the warning about circular references within the object
prototype chain. I'll have to design carefully to ensure it doesn't happen.

Thanks again David.

Cheers
Owen Brunker
 
Ad

Advertisements

G

Geoffrey Summerhayes

=== CODE START Broken Version ==================
function EventHandlers(idAnchor, idImg, ImageSrcIn, ImageSrcOut) {
var element;

this.id = idImg;
this.ImagesIn = ImageSrcIn;
this.ImagesOut = ImageSrcOut;
this.eventMouseOver = eventMouseOver;
this.eventMouseOut = eventMouseOut;

element = document.getElementById(idAnchor);
if (element != null) {
element.onmouseover = this.eventMouseOver;

Try this(untested)...

element.onmouseover=function(obj){return function()
{obj.eventMouseOver()}}(this);
 
Ad

Advertisements


Top