Sunday, January 08, 2006

addEvent()

A lots been said and done here. Here's my take if attachEvent does not give you access to the "this" pointer don't use it, instead use the age old method supported by most browsers :)
<html>
  <head>
    <title>Javascript Test Page</title>
<script type="text/javascript">
/*****************************************************************************
 *                          Helper Functions
 *****************************************************************************/
var onlyUnique = true; // default
function registerListener(target, event, listener) {
 if ( target[event + "Count"] ) {
  target[event + "Count"] = parseInt(target[event + "Count"]) + 1;
 } else {
  // first handler so add default event handler
  target[event + "Count"] = 1;
  target.defaultHandler = defaultHandler;
  target["on" + event] = function(evt) {
   evt = window.event ? window.event : evt;
   target.defaultHandler(event, evt);
  };
 }
 var currCount = parseInt(target[event + "Count"]) - 1;
 if ( onlyUnique ) {
  for ( var i = 0; i < currCount; i++ ) {
   if ( target[event + i] == listener ) {
    target[event + "Count"] = currCount;
    return false;
   }
  } // endfor i
 } // endif onlyUnique
 target[event + currCount] = listener;
 return true;
}
function unRegisterListener(target, event, listener) {
 if ( target[event + "Count"] ) {
  var currCount = parseInt(target[event + "Count"]);
  for ( var i = 0; i < currCount; i++ ) {
   if ( target[event + i] == listener ) {
    target[event + i] = null;
    currCount--; // removed one
    break;
   }
  } // endfor i
  for ( var j = i; j < currCount; j++ ) {
   target[event + j] = target[event + (j + 1)];
  } //  endfor j
  if ( currCount < 1 ) {
   // cleanup default event handler
   target["on" + event] = null;
  }
  target[event + "Count"] = currCount;
 }
}
function defaultHandler(eventName, evt) {
 if ( this[eventName + "Count"] ) {
  var currCount = parseInt(this[eventName + "Count"]);
  for ( var i = 0; i < currCount; i++ ) {
   this[eventName + i](evt);
  } // endfor i
 }
}
/*****************************************************************************
 *                  Event Handler Functions
 *****************************************************************************/
function addEvent(target, event, func) {
 if ( target.addEventListener ) {
  target.addEventListener(event, func, false);
 } else {
  registerListener(target, event, func)
 }
}
function removeEvent(target, event, func) {
 if ( target.removeEventListener ) {
  target.removeEventListener(event, func, false);
 } else {
  unRegisterListener(target, event, func)
 }
}
/*****************************************************************************/
function gel(idName) {
 return document.getElementById ? document.getElementById(idName) : false;
}
addEvent(window, "load", one);
addEvent(window, "load", two);
addEvent(window, "load", initialize);
var oneCount = 0;
function one() {
 var text = "[one][" + oneCount + "]" + this.id;
 oneCount++;
 var div = document.createElement("div");
 div.appendChild(document.createTextNode(text));
 gel("oneDiv").appendChild(div);
}
var twoCount = 0;
function two(evt) {
 var text = "[two][" + twoCount + "]" + evt.type;
 twoCount++;
 var div = document.createElement("div");
 div.appendChild(document.createTextNode(text));
 gel("twoDiv").appendChild(div);
}
function initialize() {
 alert("[initialize]");
 alert("adding one");
 add1();
 alert("adding two");
 add2();
 alert("done");
 addEvent(gel("remove1"), "click", remove1);
 addEvent(gel("remove2"), "click", remove2);
 addEvent(gel("add1"), "click", add1);
 addEvent(gel("add2"), "click", add2);
}
function remove1() {
 for ( var i = 0; i < 10; i++ ) {
  remove(one);
 }
 alert(gel("anchor").clickCount + " handler(s) left");
}
function remove2() {
 for ( var i = 0; i < 10; i++ ) {
  remove(two);
 }
 alert(gel("anchor").clickCount + " handler(s) left");
}
function remove(which) {
 removeEvent(gel("anchor"), "click", which);
}
function add1() {
 for ( var i = 0; i < 10; i++ ) {
  add(one);
 }
 alert(gel("anchor").clickCount + " handler(s) present");
}
function add2() {
 for ( var i = 0; i < 10; i++ ) {
  add(two);
 }
 alert(gel("anchor").clickCount + " handler(s) present");
}
function add(which) {
 addEvent(gel("anchor"), "click", which);
}
</script>
  </head>
  <body>
    <a id="anchor" href="#">[Test]</a>
    <a id="remove1" href="#">[Remove 1]</a>
    <a id="remove2" href="#">[Remove 2]</a>
    <a id="add1" href="#">[Add 1]</a>
    <a id="add2" href="#">[Add 2]</a>
    <div id="test"></div>
    <table>
      <tr>
        <td valign="top">
          <div id="oneDiv"></div>
        </td>
        <td valign="top">
          <div id="twoDiv"></div>
        </td>
      </tr>
    </table>
  </body>
</html>

No comments: