1 // event.js: cross-browser Listener-style event handling
2 // version 0.9, 18-Apr-2001
3 // written by Andrew Clover <and@doxdesk.com>, use freely
5 event_list= new Array();
7 event_level= 0;
8 if (document.implementation)
9 if (document.implementation.hasFeature('Events', '2.0'))
10 event_level= 2;
12 function event_addListener(esource, etype, elistener) {
13 var i;
14 var alreadyTriggering= false;
15 for (i= 0; i<event_list.length; i++) {
16 if (event_list[i][0]==esource && event_list[i][1]==etype) {
17 if (event_list[i][2]==elistener) return;
18 alreadyTriggering= true;
19 } }
20 event_list[event_list.length]= new Array(esource, etype, elistener);
21 if (!alreadyTriggering) {
22 if (event_level==2) {
23 if (esource==window && !(esource.addEventListener))
24 esource= document; // Opera 7.2
25 esource.addEventListener(etype, event_trigger_DOM2, false);
26 } else {
27 eval(event_trigger_DOM0(etype));
28 esource['on'+etype]= event_trigger;
29 if (esource.captureEvents)
30 esource.captureEvents('Event.'+etype.toUpperCase());
31 } }
32 }
34 function event_removeListener(esource, etype, elistener) {
35 var i; var e;
36 var j= 0;
37 var removedListener= false;
38 var keepTrigger= false;
39 for (i= 0; i<event_list.length; i++) {
40 if (event_list[i][0]==esource && event_list[i][1]==etype) {
41 if (event_list[i][2]==elistener) {
42 removedListener= true;
43 continue;
44 }
45 else keepTrigger= true;
46 }
47 if (i!=j) event_list[j]= event_list[i];
48 j++;
49 }
50 event_list.length= j;
51 if (removedListener && !keepTrigger) {
52 if (event_level==2)
53 esource.removeEventListener(etype, elistener, true);
54 else
55 esource['on'+etype]= window.clientInformation ? null : window.undefined;
56 }
57 }
59 function event_trigger_DOM2(e) {
60 if (event_dispatch(e.target, e.type)==false)
61 e.preventDefault();
62 }
64 function event_trigger_DOM0(t) {
65 return 'function event_trigger() {return event_dispatch(this, \''+t+'\');}';
66 }
68 function event_dispatch(esource, etype) {
69 var i; var r;
70 var elisteners= new Array();
71 var result= window.undefined;
72 for (i= 0; i<event_list.length; i++)
73 if (event_list[i][0]==esource && event_list[i][1]==etype)
74 elisteners[elisteners.length]= event_list[i][2];
75 for (i= 0; i<elisteners.length; i++) {
76 r= elisteners[i](esource, etype);
77 if (r+''!='undefined') result= r;
78 }
79 return result;
80 }
82 // convenience prevent-default-action listener
83 function event_prevent(esource, etype) { return false; }
85 // page finished loading detector for binding
86 var event_loaded= false;
87 function event_load(esource, etype) {
88 event_loaded= true;
89 event_removeListener(window, 'load', event_load);
90 }
91 event_addListener(window, 'load', event_load);
93 // binding helper
94 var event_BINDDELAY= 750;
95 var event_binds= new Array();
97 function event_addBinding(btag, blistener) {
98 event_binds[event_binds.length]= new Array(btag, 0, blistener);
99 if (event_intervalling)
100 event_bind();
101 else {
102 event_intervalling= true;
103 window.setTimeout(event_interval, 0);
104 }
105 }
107 var event_intervalling= false;
108 function event_interval() {
109 event_bind();
110 if (!event_loaded)
111 window.setTimeout(event_interval, event_BINDDELAY);
112 }
114 function event_bind() {
115 var i, j, els, blistener;
116 for (i= event_binds.length; i-->0;) {
117 els= event_getElementsByTag(event_binds[i][0]);
118 blistener= event_binds[i][2];
119 for (j= event_binds[i][1]; j<els.length; j++)
120 blistener(els[j]);
121 event_binds[i][1]= event_getElementsByTag(event_binds[i][0]).length;
122 }
123 }
125 // get elements by tag name with backup for pre-DOM browsers
126 var event_NIL= new Array();
127 function event_getElementsByTag(tag) {
128 if (document.getElementsByTagName) {
129 var arr= document.getElementsByTagName(tag);
130 // IE5.0/Win doesn't support '*' for all tags
131 if (tag!='*' || arr.length>0) return arr;
132 }
133 if (document.all) {
134 if (tag=='*') return event_array(document.all);
135 else return event_array(document.all.tags(tag));
136 }
137 tag= tag.toLowerCase();
138 if (tag=='a') return event_array(document.links);
139 if (tag=='img') return event_array(document.images);
140 if (tag=='form') return event_array(document.forms);
141 if (document.layers && tag=='div') return event_array(document.layers);
142 return event_NIL;
143 }
144 function event_array(coll) {
145 var arr= new Array(coll.length);
146 for (var i= arr.length; i-->0;)
147 arr[i]= coll[i];
148 return arr;
149 }