Event Handlers
1 HTML Inline Code
We construct a table and add an event handler to each <td> element. We do it in various ways in order to illustrate the various possibilities. When the table cell is clicked the string F in onclick=F is evaluated in the global Window context. This means that inside the event handlers the variable 'this' refers to the global object (i.e. the window). So, if we want to access the clicked element, we need to pass it as an argument to the event handler. We can also pass the event - unfortunately this does not work in IE, so the event has to be found out tediously in the event handler. Other parameter can also be passed as values.
<table>
<tr>
<td onclick='click11();'>00</td>
<td onclick='click12(this);'>00</td>
<td onclick='click13(event, this);'>00</td>
</tr>
<tr>
<td onclick='click21(2, 1, this, event);'>00</td>
<td onclick='this.row=2; this.col=2; click22(this, event);'>00</td>
<td id="td_2_3" onclick='click23(this, event);'>00</td>
</tr>
</table>
<script type="text/javascript">
function click11() {
alert("You clicked me");
}
function click12(elem) {
elem.innerHTML = elem.innerHTML=="00" ? "12" : "00";
}
function click13(evt, elem) {
// Find event e:
var e = evt || event || window.event;
if (!e) {
alert("No Event");
return;
}
// Find element from event (must be same as 'elem'):
var el = e.target || e.srcElement;
if (!el || el != elem) {
alert("Error Element");
}
el.innerHTML = elem.innerHTML=="00" ? "13" : "00";
}
function click21(row, col, elem, evt) {
// Other parameter values can be passed.
// The order is arbitrary.
var e = evt || event || window.event;
if (!e) {
alert("No Event");
return;
}
var el = e.target || e.srcElement;
if (!el || el != elem) {
alert("Error Element");
}
var val = "" + row + col;
el.innerHTML = elem.innerHTML=="00" ? val : "00";
}
function click22(elem, evt) {
// Parameters passed as properties of the clicked element.
var e = evt || event || window.event;
if (!e) {
alert("No Event");
return;
}
var el = e.target || e.srcElement;
if (!el || el != elem) {
alert("Error Element");
}
var val = "" + el.row + el.col;
el.innerHTML = elem.innerHTML=="00" ? val : "00";
}
function click23(elem, evt) {
// Find event e:
var e = evt || event || window.event;
if (!e) {
alert("No Event");
return;
}
// Find element from event (must be same as 'elem'):
var el = e.target || e.srcElement;
if (!el || el != elem) {
alert("Error Element");
}
// Get data from the 'id' attribute
var cell = el.id.split("_");
var val = "" + cell[1] + cell[2];
el.innerHTML = elem.innerHTML=="00" ? val : "00";
}
</script>
Click me !
| 00 | 00 | 00 |
| 00 | 00 | 00 |
2 Adding Handlers to DOM Elements
Event handlers can also be added to created DOM elements using Javascript. Here are various possibilities:
- Example 1.1
The element is extended by the data that are passed to the event handler click_11. The danger is overwriting of existing element properties. - Example 1.2
The data are encoded in the id attribute of the element. The event handler click_12 decodes it and gets the data. This is neither general nor elegant but handy in many cases. - Example 1.3
The event handler is created using the Function(f) constructor, where f is the body of the function as string. The variables row and col are encoded as their numerical values. - Example 1.4
The event handler is extended by the passed data as its properties. - Example 2.1
An attempt to pass local variables to the event handler fails. the event handler gets the last assigned values and even this is not guaranteed. - Example 2.2
The event handler is created using the function(), the object reference is passed as this. The variables row and col are passed as properties of the event handle. - Example 2.3
The event handler is realized by a nested function that conserves the values of its local variables in its closure. - Example 2.4
That was it.
function table(numRows, numCols) {
var row, col;
var t = "<table>";
for (row = 1; row <= numRows; ++row) {
t += "<tr>";
for (col = 1; col <= numCols; ++col) {t += td(row, col);}
t += "</tr>";
}
t += "</table>";
return t;
}
function td(row, col) {
var ID = "id_" + row + col;
var td = "<td id='" + ID + "'>00</td>";
return td;
}
function addEventHandlers() {
var r = 0;
var c = 0;
// Example 1.1
var cell_11 = document.getElementById('id_11');
cell_11.onclick = click_11;
cell_11.row = 1;
cell_11.col = 1;
// Example 1.2
var cell_12 = document.getElementById('id_12');
cell_12.onclick = click_12;
// Example 1.3
var cell_13 = document.getElementById('id_13');
r = 1; c = 3;
var f_13 = "click_13(this," + r + "," + c + ")"; // must pass this !!!
// Pattern: cell_13.onclick = new Function("click_13(this, 1, 3)");
cell_13.onclick = new Function(f_13);
// Example 1.4
var cell_14 = document.getElementById('id_14');
cell_14.onclick = click_14;
cell_14.row = 1;
cell_14.col = 4;
// Example 2.1
var cell_21 = document.getElementById('id_21');
r = 2; c = 1;
// Does not work (last assigned values r="R", c="C" are known in the handler):
cell_21.onclick = function() {click_21(this, r, c)};
// Example 2.2
var cell_22 = document.getElementById('id_22');
cell_22.onclick = function() {click_22(this)}; // must pass this !!!
cell_22.row = 2;
cell_22.col = 2;
// Example 2.3
var cell_23 = document.getElementById('id_23');
// Closure:
r = 2; c = 3;
cell_23.onclick = click_23(r, c);
// Example 2.4
var cell_24 = document.getElementById('id_24');
cell_24.onclick = click_24;
// Overwritten final values of local variables (for testing):
r = "R"; c = "C";
}
function click_11() {
// Here 'this' refers to the clicked <td>.
var val = "" + this.row + this.col;
this.innerHTML = this.innerHTML=="00" ? val : "00";
}
function click_12() {
// Here 'this' refers to the clicked <td>.
// Data is coded in this.id
var ids = this.id.split("_");
this.innerHTML = this.innerHTML=="00" ? ids[1] : "00";
}
function click_13(elem, row, col) {
// Here 'this' refers to the Window object.
var t = this;
var val = "" + row + col;
elem.innerHTML = elem.innerHTML=="00" ? val : "00";
}
function click_14(evt) {
// 'event' is passed in some (but not all) browsers
// Find event e:
var e = evt || event || window.event;
// Find element from event"
var el = e.target || e.srcElement;
var val = "" + el.row + el.col;
el.innerHTML = el.innerHTML=="00" ? val : "00";
}
function click_21(elem, row, col) {
// Here 'this' refers to the Window object
var val = "" + row + col;
elem.innerHTML = elem.innerHTML=="00" ? val : "00";
}
function click_22(elem) {
// Here 'this' refers to the Window object
var val = "" + elem.row + elem.col;
elem.innerHTML = elem.innerHTML=="00" ? val : "00";
}
function click_23(row, col) {
return function() {
// Closure: this inner function stores the values
// of row, col as they were when click_23 was called
// in addEventHandlers() above.
// 'this' refers to the clicked element because
// this inner function is the member function 'onclick' of <td>.
var val = "" + row + col;
this.innerHTML = this.innerHTML=="00" ? val : "00";
};
}
function click_24() {
this.innerHTML = "That's all :)";
this.style.cursor = "default";
}
Click me !

