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