> Hi.
>
> THE QUESTION: How do I get a reference to my Object when processing an
> event handler bound to an html element ?
> BUT...
>
[quoted text clipped - 7 lines]
>
> ie
Hi Rob,
Thanks for your reply. Firstly, sorry about the capitalisation errors. I
was abbreviating a much long object for clarity and wasnt careful enough.
I have played around with your suggestion:
ie: table.rows[r].cells[c].onclick =
function(){grid.onclickHandler.call(table);}
and have learned a lot about the .call function - thanks.
> A better strategy would be to add a single handler to the table, then
> use the event object (event.target/srcElement) to find the cell that
> was clicked on. The above creates a large number of closures and
> exercises IE's memory leak by having a circular closure involving a
> DOM element. Unless you manually remove the hanlders, you will
> eventually have memory problems.
I am unsure about this. I understand what you are saying and have tried
it but cant figure out how to get the event object using mozilla when I
am in the handler within the grid object.
eg if I do this:
Grid.prototype.addHandlers = function() {
var table = this.gridObj
table.onclick = this.onclickHandler
}
Grid.prototype.onclickHandler = function(ev) {
alert(this) // this = the table element object
var elem = eventTarget(ev) // cross browser function to get the
target alert("inhandler:"+elem) // the target element object ie the td
object
}
it works but I dont have a reference to the grid object itself.
And if I do this:
Grid.prototype.addHandlers = function() {
var grid = this;
var table = this.gridObj
table.onclick = function(){grid.onclickHandler.call(table,grid);}
}
Grid.prototype.onclickHandler = function(gridObj) {
alert(this) // this = the table element object
alert("inhandler:"+gridObj) // ie a reference to the grid object
// but no reference to the event object
}
it works but I dont have an event object to enable me to figure out how
to access the cell that was clicked.
For IE I could use the event.srcElement but how can I access the event
object with mozilla since it isnt passed in via the ev parameter ?
> The number of rows and columns need not be set as properties of the
> grid object since they can be retrieved from the table. That way if
> you modify the table by adding or deleting rows or cells, you don't
> have to update the corresponding grid object.
Indeed. That was part of the abbreviation for the example. The object
that calls the grid sets the dimensions of the grid dynamically (via a
method that I deleted from the example).
Thanks again,
Murray
RobG - 28 Feb 2007 09:20 GMT
> > A better strategy would be to add a single handler to the table, then
> > use the event object (event.target/srcElement) to find the cell that
[quoted text clipped - 6 lines]
> it but cant figure out how to get the event object using mozilla when I
> am in the handler within the grid object.
Gecko browsers (and others) will pass a reference to the event object
as the first argument to the function called by the event. IE makes
it available as the global event object.
<URL: http://www.quirksmode.org/js/introevents.html >
> eg if I do this:
> Grid.prototype.addHandlers = function() {
[quoted text clipped - 12 lines]
>
> it works but I dont have a reference to the grid object itself.
Create a closure back to it. Some browsers will let you add a
reference to the object to the DOM element, but not all (or even
enough).
> And if I do this:
> Grid.prototype.addHandlers = function() {
[quoted text clipped - 17 lines]
> For IE I could use the event.srcElement but how can I access the event
> object with mozilla since it isnt passed in via the ev parameter ?
See code below for addHandler() - note no 's'.
> > The number of rows and columns need not be set as properties of the
> > grid object since they can be retrieved from the table. That way if
[quoted text clipped - 4 lines]
> that calls the grid sets the dimensions of the grid dynamically (via a
> method that I deleted from the example).
I wouldn't set it at all, just get it from the table if or when you
need it.
Here's my test example:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<head><title>Hi</title>
<style type="text/css">
table {
border-collapse: collapse;
border-top: 1px solid blue;
border-left: 1px solid blue;
}
td {
border-bottom: 1px solid blue;
border-right: 1px solid blue;
}
</style>
<script>
function $(el) {
return (typeof el=='string')? document.getElementById(el) : el;
}
function Grid(gridNumb) {
this.gridNumb = gridNumb;
this.gridObj = $('grid_'+gridNumb);
}
Grid.prototype.onclickHandler = function() {
alert(this.rows)
}
// Old function
Grid.prototype.addHandlers = function() {
var grid = this;
var table = this.gridObj;
var row;
// Get num rows and cells from table, don't store in object
for (var r=0, len=table.rows.length; r<len; r++) {
row = table.rows[r]
for (var c=0, len2=row.cells.length; c<len2; c++) {
row.cells[c].onclick = function(){
grid.onclickHandler.call(table);
}
}
}
}
// New function
Grid.prototype.addHandler = function()
{
var grid = this;
grid.gridObj.onclick = function(e) {
var e = e || window.event;
var tgt = e.target || e.srcElement;
// Fix to get type 1 if type 3 (text node) returned
while(tgt.nodeType != 1) tgt = tgt.parentNode;
// Here's the element
alert( tgt.textContent || tgt.innerText );
// Closure back to the grid object
alert('grid is an ' + typeof grid);
}
}
window.onload = function(){
var x = new Grid('0');
x.addHandler();
}
</script>
</head>
<body>
<table id="grid_0">
<tr><td>cell 0 0<td>cell 0 1<td>cell 0 2
<tr><td>cell 1 0<td>cell 1 1<td>cell 1 2
</table>
</body>
--
Rob
Murray Hopkins - 28 Feb 2007 22:20 GMT
See the Solution I posted.