It's now possible to trigger default events like .click(), .submit(), .focus(), etc...
[jquery.git] / src / event / event.js
1 /*
2  * A number of helper functions used for managing events.
3  * Many of the ideas behind this code orignated from 
4  * Dean Edwards' addEvent library.
5  */
6 jQuery.event = {
7
8         // Bind an event to an element
9         // Original by Dean Edwards
10         add: function(element, type, handler, data) {
11                 // For whatever reason, IE has trouble passing the window object
12                 // around, causing it to be cloned in the process
13                 if ( jQuery.browser.msie && element.setInterval != undefined )
14                         element = window;
15
16                 // if data is passed, bind to handler
17                 if( data ) 
18                         handler.data = data;
19
20                 // Make sure that the function being executed has a unique ID
21                 if ( !handler.guid )
22                         handler.guid = this.guid++;
23
24                 // Init the element's event structure
25                 if (!element.events)
26                         element.events = {};
27
28                 // Get the current list of functions bound to this event
29                 var handlers = element.events[type];
30
31                 // If it hasn't been initialized yet
32                 if (!handlers) {
33                         // Init the event handler queue
34                         handlers = element.events[type] = {};
35
36                         // Remember an existing handler, if it's already there
37                         if (element["on" + type])
38                                 handlers[0] = element["on" + type];
39                 }
40
41                 // Add the function to the element's handler list
42                 handlers[handler.guid] = handler;
43
44                 // And bind the global event handler to the element
45                 element["on" + type] = this.handle;
46
47                 // Remember the function in a global list (for triggering)
48                 if (!this.global[type])
49                         this.global[type] = [];
50                 this.global[type].push( element );
51         },
52
53         guid: 1,
54         global: {},
55
56         // Detach an event or set of events from an element
57         remove: function(element, type, handler) {
58                 if (element.events)
59                         if ( type && type.type )
60                                 delete element.events[ type.type ][ type.handler.guid ];
61                         else if (type && element.events[type])
62                                 if ( handler )
63                                         delete element.events[type][handler.guid];
64                                 else
65                                         for ( var i in element.events[type] )
66                                                 delete element.events[type][i];
67                         else
68                                 for ( var j in element.events )
69                                         this.remove( element, j );
70         },
71
72         trigger: function(type,data,element) {
73                 // Clone the incoming data, if any
74                 data = jQuery.makeArray(data || []);
75
76                 // Handle a global trigger
77                 if ( !element ) {
78                         var g = this.global[type];
79                         if ( g )
80                                 for ( var i = 0, gl = g.length; i < gl; i++ )
81                                         this.trigger( type, data, g[i] );
82
83                 // Handle triggering a single element
84                 } else if ( element["on" + type] ) {
85                         if ( element[ type ] && element[ type ].constructor == Function )
86                                 element[ type ]();
87                         else {
88                                 // Pass along a fake event
89                                 data.unshift( this.fix({ type: type, target: element }) );
90         
91                                 // Trigger the event
92                                 element["on" + type].apply( element, data );
93                         }
94                 }
95         },
96
97         handle: function(event) {
98                 if ( typeof jQuery == "undefined" ) return false;
99
100                 // Empty object is for triggered events with no data
101                 event = jQuery.event.fix( event || window.event || {} ); 
102
103                 // returned undefined or false
104                 var returnValue;
105
106                 var c = this.events[event.type];
107
108                 var args = [].slice.call( arguments, 1 );
109                 args.unshift( event );
110
111                 for ( var j in c ) {
112                         // Pass in a reference to the handler function itself
113                         // So that we can later remove it
114                         args[0].handler = c[j];
115                         args[0].data = c[j].data;
116
117                         if ( c[j].apply( this, args ) === false ) {
118                                 event.preventDefault();
119                                 event.stopPropagation();
120                                 returnValue = false;
121                         }
122                 }
123
124                 // Clean up added properties in IE to prevent memory leak
125                 if (jQuery.browser.msie) event.target = event.preventDefault = event.stopPropagation = event.handler = event.data = null;
126
127                 return returnValue;
128         },
129
130         fix: function(event) {
131                 // Fix target property, if necessary
132                 if ( !event.target && event.srcElement )
133                         event.target = event.srcElement;
134
135                 // Calculate pageX/Y if missing and clientX/Y available
136                 if ( typeof event.pageX == "undefined" && typeof event.clientX != "undefined" ) {
137                         var e = document.documentElement, b = document.body;
138                         event.pageX = event.clientX + (e.scrollLeft || b.scrollLeft);
139                         event.pageY = event.clientY + (e.scrollTop || b.scrollTop);
140                 }
141                                 
142                 // check if target is a textnode (safari)
143                 if (event.target.nodeType == 3) {
144                         // store a copy of the original event object 
145                         // and clone because target is read only
146                         var originalEvent = event;
147                         event = jQuery.extend({}, originalEvent);
148                         
149                         // get parentnode from textnode
150                         event.target = originalEvent.target.parentNode;
151                         
152                         // add preventDefault and stopPropagation since 
153                         // they will not work on the clone
154                         event.preventDefault = function() {
155                                 return originalEvent.preventDefault();
156                         };
157                         event.stopPropagation = function() {
158                                 return originalEvent.stopPropagation();
159                         };
160                 }
161                 
162                 // fix preventDefault and stopPropagation
163                 if (!event.preventDefault)
164                         event.preventDefault = function() {
165                                 this.returnValue = false;
166                         };
167                         
168                 if (!event.stopPropagation)
169                         event.stopPropagation = function() {
170                                 this.cancelBubble = true;
171                         };
172                         
173                 return event;
174         }
175 };
176
177 jQuery.fn.extend({
178
179         /**
180          * Binds a handler to a particular event (like click) for each matched element.
181          * The event handler is passed an event object that you can use to prevent
182          * default behaviour. To stop both default action and event bubbling, your handler
183          * has to return false.
184          *
185          * In most cases, you can define your event handlers as anonymous functions
186          * (see first example). In cases where that is not possible, you can pass additional
187          * data as the second paramter (and the handler function as the third), see 
188          * second example.
189          *
190          * @example $("p").bind( "click", function() {
191          *   alert( $(this).text() );
192          * } )
193          * @before <p>Hello</p>
194          * @result alert("Hello")
195          *
196          * @example var handler = function(event) {
197          *   alert(event.data.foo);
198          * };
199          * $("p").bind( "click", {foo: "bar"}, handler)
200          * @result alert("bar")
201          * @desc Pass some additional data to the event handler.
202          *
203          * @example $("form").bind( "submit", function() { return false; } )
204          * @desc Cancel a default action and prevent it from bubbling by returning false
205          * from your function.
206          *
207          * @example $("form").bind( "submit", function(event) {
208          *   event.preventDefault();
209          * } );
210          * @desc Cancel only the default action by using the preventDefault method.
211          *
212          *
213          * @example $("form").bind( "submit", function(event) {
214          *   event.stopPropagation();
215          * } )
216          * @desc Stop only an event from bubbling by using the stopPropagation method.
217          *
218          * @name bind
219          * @type jQuery
220          * @param String type An event type
221          * @param Object data (optional) Additional data passed to the event handler as event.data
222          * @param Function fn A function to bind to the event on each of the set of matched elements
223          * @cat Events
224          */
225         bind: function( type, data, fn ) {
226                 return this.each(function(){
227                         jQuery.event.add( this, type, fn || data, data );
228                 });
229         },
230         
231         /**
232          * Binds a handler to a particular event (like click) for each matched element.
233          * The handler is executed only once for each element. Otherwise, the same rules
234          * as described in bind() apply.
235          The event handler is passed an event object that you can use to prevent
236          * default behaviour. To stop both default action and event bubbling, your handler
237          * has to return false.
238          *
239          * In most cases, you can define your event handlers as anonymous functions
240          * (see first example). In cases where that is not possible, you can pass additional
241          * data as the second paramter (and the handler function as the third), see 
242          * second example.
243          *
244          * @example $("p").one( "click", function() {
245          *   alert( $(this).text() );
246          * } )
247          * @before <p>Hello</p>
248          * @result alert("Hello")
249          *
250          * @name one
251          * @type jQuery
252          * @param String type An event type
253          * @param Object data (optional) Additional data passed to the event handler as event.data
254          * @param Function fn A function to bind to the event on each of the set of matched elements
255          * @cat Events
256          */
257         one: function( type, data, fn ) {
258                 return this.each(function(){
259                         jQuery.event.add( this, type, function(event) {
260                                 jQuery(this).unbind(event);
261                                 return (fn || data).apply( this, arguments);
262                         }, data);
263                 });
264         },
265
266         /**
267          * The opposite of bind, removes a bound event from each of the matched
268          * elements. You must pass the identical function that was used in the original
269          * bind method.
270          *
271          * @example $("p").unbind( "click", function() { alert("Hello"); } )
272          * @before <p onclick="alert('Hello');">Hello</p>
273          * @result [ <p>Hello</p> ]
274          *
275          * @name unbind
276          * @type jQuery
277          * @param String type An event type
278          * @param Function fn A function to unbind from the event on each of the set of matched elements
279          * @cat Events
280          */
281
282         /**
283          * Removes all bound events of a particular type from each of the matched
284          * elements.
285          *
286          * @example $("p").unbind( "click" )
287          * @before <p onclick="alert('Hello');">Hello</p>
288          * @result [ <p>Hello</p> ]
289          *
290          * @name unbind
291          * @type jQuery
292          * @param String type An event type
293          * @cat Events
294          */
295
296         /**
297          * Removes all bound events from each of the matched elements.
298          *
299          * @example $("p").unbind()
300          * @before <p onclick="alert('Hello');">Hello</p>
301          * @result [ <p>Hello</p> ]
302          *
303          * @name unbind
304          * @type jQuery
305          * @cat Events
306          */
307         unbind: function( type, fn ) {
308                 return this.each(function(){
309                         jQuery.event.remove( this, type, fn );
310                 });
311         },
312
313         /**
314          * Trigger a type of event on every matched element.
315          *
316          * @example $("p").trigger("click")
317          * @before <p click="alert('hello')">Hello</p>
318          * @result alert('hello')
319          *
320          * @name trigger
321          * @type jQuery
322          * @param String type An event type to trigger.
323          * @cat Events
324          */
325         trigger: function( type, data ) {
326                 return this.each(function(){
327                         jQuery.event.trigger( type, data, this );
328                 });
329         },
330
331         // We're overriding the old toggle function, so
332         // remember it for later
333         _toggle: jQuery.fn.toggle,
334         
335         /**
336          * Toggle between two function calls every other click.
337          * Whenever a matched element is clicked, the first specified function 
338          * is fired, when clicked again, the second is fired. All subsequent 
339          * clicks continue to rotate through the two functions.
340          *
341          * Use unbind("click") to remove.
342          *
343          * @example $("p").toggle(function(){
344          *   $(this).addClass("selected");
345          * },function(){
346          *   $(this).removeClass("selected");
347          * });
348          * 
349          * @name toggle
350          * @type jQuery
351          * @param Function even The function to execute on every even click.
352          * @param Function odd The function to execute on every odd click.
353          * @cat Events
354          */
355         toggle: function() {
356                 // save reference to arguments for access in closure
357                 var a = arguments;
358                 return typeof a[0] == "function" && typeof a[1] == "function" ? this.click(function(e) {
359                         // Figure out which function to execute
360                         this.lastToggle = this.lastToggle == 0 ? 1 : 0;
361                         
362                         // Make sure that clicks stop
363                         e.preventDefault();
364                         
365                         // and execute the function
366                         return a[this.lastToggle].apply( this, [e] ) || false;
367                 }) :
368                 
369                 // Otherwise, execute the old toggle function
370                 this._toggle.apply( this, arguments );
371         },
372         
373         /**
374          * A method for simulating hovering (moving the mouse on, and off,
375          * an object). This is a custom method which provides an 'in' to a 
376          * frequent task.
377          *
378          * Whenever the mouse cursor is moved over a matched 
379          * element, the first specified function is fired. Whenever the mouse 
380          * moves off of the element, the second specified function fires. 
381          * Additionally, checks are in place to see if the mouse is still within 
382          * the specified element itself (for example, an image inside of a div), 
383          * and if it is, it will continue to 'hover', and not move out 
384          * (a common error in using a mouseout event handler).
385          *
386          * @example $("p").hover(function(){
387          *   $(this).addClass("over");
388          * },function(){
389          *   $(this).addClass("out");
390          * });
391          *
392          * @name hover
393          * @type jQuery
394          * @param Function over The function to fire whenever the mouse is moved over a matched element.
395          * @param Function out The function to fire whenever the mouse is moved off of a matched element.
396          * @cat Events
397          */
398         hover: function(f,g) {
399                 
400                 // A private function for handling mouse 'hovering'
401                 function handleHover(e) {
402                         // Check if mouse(over|out) are still within the same parent element
403                         var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
404         
405                         // Traverse up the tree
406                         while ( p && p != this ) try { p = p.parentNode } catch(e) { p = this; };
407                         
408                         // If we actually just moused on to a sub-element, ignore it
409                         if ( p == this ) return false;
410                         
411                         // Execute the right function
412                         return (e.type == "mouseover" ? f : g).apply(this, [e]);
413                 }
414                 
415                 // Bind the function to the two event listeners
416                 return this.mouseover(handleHover).mouseout(handleHover);
417         },
418         
419         /**
420          * Bind a function to be executed whenever the DOM is ready to be
421          * traversed and manipulated. This is probably the most important 
422          * function included in the event module, as it can greatly improve
423          * the response times of your web applications.
424          *
425          * In a nutshell, this is a solid replacement for using window.onload, 
426          * and attaching a function to that. By using this method, your bound Function 
427          * will be called the instant the DOM is ready to be read and manipulated, 
428          * which is exactly what 99.99% of all Javascript code needs to run.
429          * 
430          * Please ensure you have no code in your &lt;body&gt; onload event handler, 
431          * otherwise $(document).ready() may not fire.
432          *
433          * You can have as many $(document).ready events on your page as you like.
434          * The functions are then executed in the order they were added.
435          *
436          * @example $(document).ready(function(){ Your code here... });
437          *
438          * @name ready
439          * @type jQuery
440          * @param Function fn The function to be executed when the DOM is ready.
441          * @cat Events
442          */
443         ready: function(f) {
444                 // If the DOM is already ready
445                 if ( jQuery.isReady )
446                         // Execute the function immediately
447                         f.apply( document );
448                         
449                 // Otherwise, remember the function for later
450                 else {
451                         // Add the function to the wait list
452                         jQuery.readyList.push( f );
453                 }
454         
455                 return this;
456         }
457 });
458
459 jQuery.extend({
460         /*
461          * All the code that makes DOM Ready work nicely.
462          */
463         isReady: false,
464         readyList: [],
465         
466         // Handle when the DOM is ready
467         ready: function() {
468                 // Make sure that the DOM is not already loaded
469                 if ( !jQuery.isReady ) {
470                         // Remember that the DOM is ready
471                         jQuery.isReady = true;
472                         
473                         // If there are functions bound, to execute
474                         if ( jQuery.readyList ) {
475                                 // Execute all of them
476                                 for ( var i = 0; i < jQuery.readyList.length; i++ )
477                                         jQuery.readyList[i].apply( document );
478                                 
479                                 // Reset the list of functions
480                                 jQuery.readyList = null;
481                         }
482                         // Remove event lisenter to avoid memory leak
483                         if ( jQuery.browser.mozilla || jQuery.browser.opera )
484                                 document.removeEventListener( "DOMContentLoaded", jQuery.ready, false );
485                 }
486         }
487 });
488
489 new function(){
490
491         /**
492          * Bind a function to the scroll event of each matched element.
493          *
494          * @example $("p").scroll( function() { alert("Hello"); } );
495          * @before <p>Hello</p>
496          * @result <p onscroll="alert('Hello');">Hello</p>
497          *
498          * @name scroll
499          * @type jQuery
500          * @param Function fn A function to bind to the scroll event on each of the matched elements.
501          * @cat Events/Browser
502          */
503
504         /**
505          * Trigger the scroll event of each matched element. This causes all of the functions
506          * that have been bound to thet scroll event to be executed.
507          *
508          * @example $("p").scroll();
509          * @before <p onscroll="alert('Hello');">Hello</p>
510          * @result alert('Hello');
511          *
512          * @name scroll
513          * @type jQuery
514          * @cat Events/Browser
515          */
516
517         /**
518          * Bind a function to the submit event of each matched element.
519          *
520          * @example $("#myform").submit( function() {
521          *   return $("input", this).val().length > 0;
522          * } );
523          * @before <form id="myform"><input /></form>
524          * @desc Prevents the form submission when the input has no value entered.
525          *
526          * @name submit
527          * @type jQuery
528          * @param Function fn A function to bind to the submit event on each of the matched elements.
529          * @cat Events/Form
530          */
531
532         /**
533          * Trigger the submit event of each matched element. This causes all of the functions
534          * that have been bound to thet submit event to be executed.
535          *
536          * Note: This does not execute the submit method of the form element! If you need to
537          * submit the form via code, you have to use the DOM method, eg. $("form")[0].submit();
538          *
539          * @example $("form").submit();
540          * @desc Triggers all submit events registered for forms, but does not submit the form
541          *
542          * @name submit
543          * @type jQuery
544          * @cat Events/Form
545          */
546
547         /**
548          * Bind a function to the focus event of each matched element.
549          *
550          * @example $("p").focus( function() { alert("Hello"); } );
551          * @before <p>Hello</p>
552          * @result <p onfocus="alert('Hello');">Hello</p>
553          *
554          * @name focus
555          * @type jQuery
556          * @param Function fn A function to bind to the focus event on each of the matched elements.
557          * @cat Events/UI
558          */
559
560         /**
561          * Trigger the focus event of each matched element. This causes all of the functions
562          * that have been bound to thet focus event to be executed.
563          *
564          * Note: This does not execute the focus method of the underlying elements! If you need to
565          * focus an element via code, you have to use the DOM method, eg. $("#myinput")[0].focus();
566          *
567          * @example $("p").focus();
568          * @before <p onfocus="alert('Hello');">Hello</p>
569          * @result alert('Hello');
570          *
571          * @name focus
572          * @type jQuery
573          * @cat Events/UI
574          */
575
576         /**
577          * Bind a function to the keydown event of each matched element.
578          *
579          * @example $("p").keydown( function() { alert("Hello"); } );
580          * @before <p>Hello</p>
581          * @result <p onkeydown="alert('Hello');">Hello</p>
582          *
583          * @name keydown
584          * @type jQuery
585          * @param Function fn A function to bind to the keydown event on each of the matched elements.
586          * @cat Events/Keyboard
587          */
588
589         /**
590          * Trigger the keydown event of each matched element. This causes all of the functions
591          * that have been bound to thet keydown event to be executed.
592          *
593          * @example $("p").keydown();
594          * @before <p onkeydown="alert('Hello');">Hello</p>
595          * @result alert('Hello');
596          *
597          * @name keydown
598          * @type jQuery
599          * @cat Events/Keyboard
600          */
601
602         /**
603          * Bind a function to the dblclick event of each matched element.
604          *
605          * @example $("p").dblclick( function() { alert("Hello"); } );
606          * @before <p>Hello</p>
607          * @result <p ondblclick="alert('Hello');">Hello</p>
608          *
609          * @name dblclick
610          * @type jQuery
611          * @param Function fn A function to bind to the dblclick event on each of the matched elements.
612          * @cat Events/Mouse
613          */
614
615         /**
616          * Trigger the dblclick event of each matched element. This causes all of the functions
617          * that have been bound to thet dblclick event to be executed.
618          *
619          * @example $("p").dblclick();
620          * @before <p ondblclick="alert('Hello');">Hello</p>
621          * @result alert('Hello');
622          *
623          * @name dblclick
624          * @type jQuery
625          * @cat Events/Mouse
626          */
627
628         /**
629          * Bind a function to the keypress event of each matched element.
630          *
631          * @example $("p").keypress( function() { alert("Hello"); } );
632          * @before <p>Hello</p>
633          * @result <p onkeypress="alert('Hello');">Hello</p>
634          *
635          * @name keypress
636          * @type jQuery
637          * @param Function fn A function to bind to the keypress event on each of the matched elements.
638          * @cat Events/Keyboard
639          */
640
641         /**
642          * Trigger the keypress event of each matched element. This causes all of the functions
643          * that have been bound to thet keypress event to be executed.
644          *
645          * @example $("p").keypress();
646          * @before <p onkeypress="alert('Hello');">Hello</p>
647          * @result alert('Hello');
648          *
649          * @name keypress
650          * @type jQuery
651          * @cat Events/Keyboard
652          */
653
654         /**
655          * Bind a function to the error event of each matched element.
656          *
657          * @example $("p").error( function() { alert("Hello"); } );
658          * @before <p>Hello</p>
659          * @result <p onerror="alert('Hello');">Hello</p>
660          *
661          * @name error
662          * @type jQuery
663          * @param Function fn A function to bind to the error event on each of the matched elements.
664          * @cat Events/Browser
665          */
666
667         /**
668          * Trigger the error event of each matched element. This causes all of the functions
669          * that have been bound to thet error event to be executed.
670          *
671          * @example $("p").error();
672          * @before <p onerror="alert('Hello');">Hello</p>
673          * @result alert('Hello');
674          *
675          * @name error
676          * @type jQuery
677          * @cat Events/Browser
678          */
679
680         /**
681          * Bind a function to the blur event of each matched element.
682          *
683          * @example $("p").blur( function() { alert("Hello"); } );
684          * @before <p>Hello</p>
685          * @result <p onblur="alert('Hello');">Hello</p>
686          *
687          * @name blur
688          * @type jQuery
689          * @param Function fn A function to bind to the blur event on each of the matched elements.
690          * @cat Events/UI
691          */
692
693         /**
694          * Trigger the blur event of each matched element. This causes all of the functions
695          * that have been bound to thet blur event to be executed.
696          *
697          * Note: This does not execute the blur method of the underlying elements! If you need to
698          * blur an element via code, you have to use the DOM method, eg. $("#myinput")[0].blur();
699          *
700          * @example $("p").blur();
701          * @before <p onblur="alert('Hello');">Hello</p>
702          * @result alert('Hello');
703          *
704          * @name blur
705          * @type jQuery
706          * @cat Events/UI
707          */
708
709         /**
710          * Bind a function to the load event of each matched element.
711          *
712          * @example $("p").load( function() { alert("Hello"); } );
713          * @before <p>Hello</p>
714          * @result <p onload="alert('Hello');">Hello</p>
715          *
716          * @name load
717          * @type jQuery
718          * @param Function fn A function to bind to the load event on each of the matched elements.
719          * @cat Events/Browser
720          */
721
722         /**
723          * Trigger the load event of each matched element. This causes all of the functions
724          * that have been bound to thet load event to be executed.
725          *
726          * Marked as private: Calling load() without arguments throws exception because the ajax load
727          * does not handle it.
728          *
729          * @example $("p").load();
730          * @before <p onload="alert('Hello');">Hello</p>
731          * @result alert('Hello');
732          *
733          * @name load
734          * @private
735          * @type jQuery
736          * @cat Events/Browser
737          */
738
739         /**
740          * Bind a function to the select event of each matched element.
741          *
742          * @example $("p").select( function() { alert("Hello"); } );
743          * @before <p>Hello</p>
744          * @result <p onselect="alert('Hello');">Hello</p>
745          *
746          * @name select
747          * @type jQuery
748          * @param Function fn A function to bind to the select event on each of the matched elements.
749          * @cat Events/Form
750          */
751
752         /**
753          * Trigger the select event of each matched element. This causes all of the functions
754          * that have been bound to thet select event to be executed.
755          *
756          * @example $("p").select();
757          * @before <p onselect="alert('Hello');">Hello</p>
758          * @result alert('Hello');
759          *
760          * @name select
761          * @type jQuery
762          * @cat Events/Form
763          */
764
765         /**
766          * Bind a function to the mouseup event of each matched element.
767          *
768          * @example $("p").mouseup( function() { alert("Hello"); } );
769          * @before <p>Hello</p>
770          * @result <p onmouseup="alert('Hello');">Hello</p>
771          *
772          * @name mouseup
773          * @type jQuery
774          * @param Function fn A function to bind to the mouseup event on each of the matched elements.
775          * @cat Events/Mouse
776          */
777
778         /**
779          * Trigger the mouseup event of each matched element. This causes all of the functions
780          * that have been bound to thet mouseup event to be executed.
781          *
782          * @example $("p").mouseup();
783          * @before <p onmouseup="alert('Hello');">Hello</p>
784          * @result alert('Hello');
785          *
786          * @name mouseup
787          * @type jQuery
788          * @cat Events/Mouse
789          */
790
791         /**
792          * Bind a function to the unload event of each matched element.
793          *
794          * @example $("p").unload( function() { alert("Hello"); } );
795          * @before <p>Hello</p>
796          * @result <p onunload="alert('Hello');">Hello</p>
797          *
798          * @name unload
799          * @type jQuery
800          * @param Function fn A function to bind to the unload event on each of the matched elements.
801          * @cat Events/Browser
802          */
803
804         /**
805          * Trigger the unload event of each matched element. This causes all of the functions
806          * that have been bound to thet unload event to be executed.
807          *
808          * @example $("p").unload();
809          * @before <p onunload="alert('Hello');">Hello</p>
810          * @result alert('Hello');
811          *
812          * @name unload
813          * @type jQuery
814          * @cat Events/Browser
815          */
816
817         /**
818          * Bind a function to the change event of each matched element.
819          *
820          * @example $("p").change( function() { alert("Hello"); } );
821          * @before <p>Hello</p>
822          * @result <p onchange="alert('Hello');">Hello</p>
823          *
824          * @name change
825          * @type jQuery
826          * @param Function fn A function to bind to the change event on each of the matched elements.
827          * @cat Events/Form
828          */
829
830         /**
831          * Trigger the change event of each matched element. This causes all of the functions
832          * that have been bound to thet change event to be executed.
833          *
834          * @example $("p").change();
835          * @before <p onchange="alert('Hello');">Hello</p>
836          * @result alert('Hello');
837          *
838          * @name change
839          * @type jQuery
840          * @cat Events/Form
841          */
842
843         /**
844          * Bind a function to the mouseout event of each matched element.
845          *
846          * @example $("p").mouseout( function() { alert("Hello"); } );
847          * @before <p>Hello</p>
848          * @result <p onmouseout="alert('Hello');">Hello</p>
849          *
850          * @name mouseout
851          * @type jQuery
852          * @param Function fn A function to bind to the mouseout event on each of the matched elements.
853          * @cat Events/Mouse
854          */
855
856         /**
857          * Trigger the mouseout event of each matched element. This causes all of the functions
858          * that have been bound to thet mouseout event to be executed.
859          *
860          * @example $("p").mouseout();
861          * @before <p onmouseout="alert('Hello');">Hello</p>
862          * @result alert('Hello');
863          *
864          * @name mouseout
865          * @type jQuery
866          * @cat Events/Mouse
867          */
868
869         /**
870          * Bind a function to the keyup event of each matched element.
871          *
872          * @example $("p").keyup( function() { alert("Hello"); } );
873          * @before <p>Hello</p>
874          * @result <p onkeyup="alert('Hello');">Hello</p>
875          *
876          * @name keyup
877          * @type jQuery
878          * @param Function fn A function to bind to the keyup event on each of the matched elements.
879          * @cat Events/Keyboard
880          */
881
882         /**
883          * Trigger the keyup event of each matched element. This causes all of the functions
884          * that have been bound to thet keyup event to be executed.
885          *
886          * @example $("p").keyup();
887          * @before <p onkeyup="alert('Hello');">Hello</p>
888          * @result alert('Hello');
889          *
890          * @name keyup
891          * @type jQuery
892          * @cat Events/Keyboard
893          */
894
895         /**
896          * Bind a function to the click event of each matched element.
897          *
898          * @example $("p").click( function() { alert("Hello"); } );
899          * @before <p>Hello</p>
900          * @result <p onclick="alert('Hello');">Hello</p>
901          *
902          * @name click
903          * @type jQuery
904          * @param Function fn A function to bind to the click event on each of the matched elements.
905          * @cat Events/Mouse
906          */
907
908         /**
909          * Trigger the click event of each matched element. This causes all of the functions
910          * that have been bound to thet click event to be executed.
911          *
912          * @example $("p").click();
913          * @before <p onclick="alert('Hello');">Hello</p>
914          * @result alert('Hello');
915          *
916          * @name click
917          * @type jQuery
918          * @cat Events/Mouse
919          */
920
921         /**
922          * Bind a function to the resize event of each matched element.
923          *
924          * @example $("p").resize( function() { alert("Hello"); } );
925          * @before <p>Hello</p>
926          * @result <p onresize="alert('Hello');">Hello</p>
927          *
928          * @name resize
929          * @type jQuery
930          * @param Function fn A function to bind to the resize event on each of the matched elements.
931          * @cat Events/Browser
932          */
933
934         /**
935          * Trigger the resize event of each matched element. This causes all of the functions
936          * that have been bound to thet resize event to be executed.
937          *
938          * @example $("p").resize();
939          * @before <p onresize="alert('Hello');">Hello</p>
940          * @result alert('Hello');
941          *
942          * @name resize
943          * @type jQuery
944          * @cat Events/Browser
945          */
946
947         /**
948          * Bind a function to the mousemove event of each matched element.
949          *
950          * @example $("p").mousemove( function() { alert("Hello"); } );
951          * @before <p>Hello</p>
952          * @result <p onmousemove="alert('Hello');">Hello</p>
953          *
954          * @name mousemove
955          * @type jQuery
956          * @param Function fn A function to bind to the mousemove event on each of the matched elements.
957          * @cat Events/Mouse
958          */
959
960         /**
961          * Trigger the mousemove event of each matched element. This causes all of the functions
962          * that have been bound to thet mousemove event to be executed.
963          *
964          * @example $("p").mousemove();
965          * @before <p onmousemove="alert('Hello');">Hello</p>
966          * @result alert('Hello');
967          *
968          * @name mousemove
969          * @type jQuery
970          * @cat Events/Mouse
971          */
972
973         /**
974          * Bind a function to the mousedown event of each matched element.
975          *
976          * @example $("p").mousedown( function() { alert("Hello"); } );
977          * @before <p>Hello</p>
978          * @result <p onmousedown="alert('Hello');">Hello</p>
979          *
980          * @name mousedown
981          * @type jQuery
982          * @param Function fn A function to bind to the mousedown event on each of the matched elements.
983          * @cat Events/Mouse
984          */
985
986         /**
987          * Trigger the mousedown event of each matched element. This causes all of the functions
988          * that have been bound to thet mousedown event to be executed.
989          *
990          * @example $("p").mousedown();
991          * @before <p onmousedown="alert('Hello');">Hello</p>
992          * @result alert('Hello');
993          *
994          * @name mousedown
995          * @type jQuery
996          * @cat Events/Mouse
997          */
998          
999         /**
1000          * Bind a function to the mouseover event of each matched element.
1001          *
1002          * @example $("p").mouseover( function() { alert("Hello"); } );
1003          * @before <p>Hello</p>
1004          * @result <p onmouseover="alert('Hello');">Hello</p>
1005          *
1006          * @name mouseover
1007          * @type jQuery
1008          * @param Function fn A function to bind to the mousedown event on each of the matched elements.
1009          * @cat Events/Mouse
1010          */
1011
1012         /**
1013          * Trigger the mouseover event of each matched element. This causes all of the functions
1014          * that have been bound to thet mousedown event to be executed.
1015          *
1016          * @example $("p").mouseover();
1017          * @before <p onmouseover="alert('Hello');">Hello</p>
1018          * @result alert('Hello');
1019          *
1020          * @name mouseover
1021          * @type jQuery
1022          * @cat Events/Mouse
1023          */
1024
1025         var e = ("blur,focus,load,resize,scroll,unload,click,dblclick," +
1026                 "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + 
1027                 "submit,keydown,keypress,keyup,error").split(",");
1028
1029         // Go through all the event names, but make sure that
1030         // it is enclosed properly
1031         for ( var i = 0; i < e.length; i++ ) new function(){
1032                         
1033                 var o = e[i];
1034                 
1035                 // Handle event binding
1036                 jQuery.fn[o] = function(f){
1037                         return f ? this.bind(o, f) : this.trigger(o);
1038                 };
1039                         
1040         };
1041         
1042         // If Mozilla is used
1043         if ( jQuery.browser.mozilla || jQuery.browser.opera )
1044                 // Use the handy event callback
1045                 document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
1046         
1047         // If IE is used, use the excellent hack by Matthias Miller
1048         // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
1049         else if ( jQuery.browser.msie ) {
1050         
1051                 // Only works if you document.write() it
1052                 document.write("<scr" + "ipt id=__ie_init defer=true " + 
1053                         "src=//:><\/script>");
1054         
1055                 // Use the defer script hack
1056                 var script = document.getElementById("__ie_init");
1057                 
1058                 // script does not exist if jQuery is loaded dynamically
1059                 if ( script ) 
1060                         script.onreadystatechange = function() {
1061                                 if ( this.readyState != "complete" ) return;
1062                                 this.parentNode.removeChild( this );
1063                                 jQuery.ready();
1064                         };
1065         
1066                 // Clear from memory
1067                 script = null;
1068         
1069         // If Safari  is used
1070         } else if ( jQuery.browser.safari )
1071                 // Continually check to see if the document.readyState is valid
1072                 jQuery.safariTimer = setInterval(function(){
1073                         // loaded and complete are both valid states
1074                         if ( document.readyState == "loaded" || 
1075                                 document.readyState == "complete" ) {
1076         
1077                                 // If either one are found, remove the timer
1078                                 clearInterval( jQuery.safariTimer );
1079                                 jQuery.safariTimer = null;
1080         
1081                                 // and execute any waiting functions
1082                                 jQuery.ready();
1083                         }
1084                 }, 10); 
1085
1086         // A fallback to window.onload, that will always work
1087         jQuery.event.add( window, "load", jQuery.ready );
1088         
1089 };
1090
1091 // Clean up after IE to avoid memory leaks
1092 if (jQuery.browser.msie)
1093         jQuery(window).bind("unload", function() {
1094                 var global = jQuery.event.global;
1095                 for ( var type in global ) {
1096                         var els = global[type], i = els.length;
1097                         if ( i && type != 'unload' )
1098                                 do
1099                                         jQuery.event.remove(els[i-1], type);
1100                                 while (--i);
1101                 }
1102         });