Removed unnecessary uses of typeof undefined.
[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 ( event.pageX == undefined && 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 (jQuery.browser.safari && 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 function handler(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.
269          *
270          * Without any arguments, all bound events are removed.
271          *
272          * If the type is provided, all bound events of that type are removed.
273          *
274          * If the function that was passed to bind is provided as the second argument,
275          * only that specific event handler is removed.
276          *
277          * @example $("p").unbind()
278          * @before <p onclick="alert('Hello');">Hello</p>
279          * @result [ <p>Hello</p> ]
280          *
281          * @example $("p").unbind( "click" )
282          * @before <p onclick="alert('Hello');">Hello</p>
283          * @result [ <p>Hello</p> ]
284          *
285          * @example $("p").unbind( "click", function() { alert("Hello"); } )
286          * @before <p onclick="alert('Hello');">Hello</p>
287          * @result [ <p>Hello</p> ]
288          *
289          * @name unbind
290          * @type jQuery
291          * @param String type (optional) An event type
292          * @param Function fn (optional) A function to unbind from the event on each of the set of matched elements
293          * @cat Events
294          */
295         unbind: function( type, fn ) {
296                 return this.each(function(){
297                         jQuery.event.remove( this, type, fn );
298                 });
299         },
300
301         /**
302          * Trigger a type of event on every matched element.
303          *
304          * @example $("p").trigger("click")
305          * @before <p click="alert('hello')">Hello</p>
306          * @result alert('hello')
307          *
308          * @name trigger
309          * @type jQuery
310          * @param String type An event type to trigger.
311          * @cat Events
312          */
313         trigger: function( type, data ) {
314                 return this.each(function(){
315                         jQuery.event.trigger( type, data, this );
316                 });
317         },
318
319         /**
320          * Toggle between two function calls every other click.
321          * Whenever a matched element is clicked, the first specified function 
322          * is fired, when clicked again, the second is fired. All subsequent 
323          * clicks continue to rotate through the two functions.
324          *
325          * Use unbind("click") to remove.
326          *
327          * @example $("p").toggle(function(){
328          *   $(this).addClass("selected");
329          * },function(){
330          *   $(this).removeClass("selected");
331          * });
332          * 
333          * @name toggle
334          * @type jQuery
335          * @param Function even The function to execute on every even click.
336          * @param Function odd The function to execute on every odd click.
337          * @cat Events
338          */
339         toggle: function() {
340                 // Save reference to arguments for access in closure
341                 var a = arguments;
342
343                 return this.click(function(e) {
344                         // Figure out which function to execute
345                         this.lastToggle = this.lastToggle == 0 ? 1 : 0;
346                         
347                         // Make sure that clicks stop
348                         e.preventDefault();
349                         
350                         // and execute the function
351                         return a[this.lastToggle].apply( this, [e] ) || false;
352                 });
353         },
354         
355         /**
356          * A method for simulating hovering (moving the mouse on, and off,
357          * an object). This is a custom method which provides an 'in' to a 
358          * frequent task.
359          *
360          * Whenever the mouse cursor is moved over a matched 
361          * element, the first specified function is fired. Whenever the mouse 
362          * moves off of the element, the second specified function fires. 
363          * Additionally, checks are in place to see if the mouse is still within 
364          * the specified element itself (for example, an image inside of a div), 
365          * and if it is, it will continue to 'hover', and not move out 
366          * (a common error in using a mouseout event handler).
367          *
368          * @example $("p").hover(function(){
369          *   $(this).addClass("over");
370          * },function(){
371          *   $(this).addClass("out");
372          * });
373          *
374          * @name hover
375          * @type jQuery
376          * @param Function over The function to fire whenever the mouse is moved over a matched element.
377          * @param Function out The function to fire whenever the mouse is moved off of a matched element.
378          * @cat Events
379          */
380         hover: function(f,g) {
381                 
382                 // A private function for handling mouse 'hovering'
383                 function handleHover(e) {
384                         // Check if mouse(over|out) are still within the same parent element
385                         var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
386         
387                         // Traverse up the tree
388                         while ( p && p != this ) try { p = p.parentNode } catch(e) { p = this; };
389                         
390                         // If we actually just moused on to a sub-element, ignore it
391                         if ( p == this ) return false;
392                         
393                         // Execute the right function
394                         return (e.type == "mouseover" ? f : g).apply(this, [e]);
395                 }
396                 
397                 // Bind the function to the two event listeners
398                 return this.mouseover(handleHover).mouseout(handleHover);
399         },
400         
401         /**
402          * Bind a function to be executed whenever the DOM is ready to be
403          * traversed and manipulated. This is probably the most important 
404          * function included in the event module, as it can greatly improve
405          * the response times of your web applications.
406          *
407          * In a nutshell, this is a solid replacement for using window.onload, 
408          * and attaching a function to that. By using this method, your bound Function 
409          * will be called the instant the DOM is ready to be read and manipulated, 
410          * which is exactly what 99.99% of all Javascript code needs to run.
411          *
412          * There is one argument passed to the ready event handler: A reference to
413          * the jQuery function. You can name that argument whatever you like, and
414          * can therefore stick with the $ alias without risc of naming collisions.
415          * 
416          * Please ensure you have no code in your &lt;body&gt; onload event handler, 
417          * otherwise $(document).ready() may not fire.
418          *
419          * You can have as many $(document).ready events on your page as you like.
420          * The functions are then executed in the order they were added.
421          *
422          * @example $(document).ready(function(){ Your code here... });
423          *
424          * @example jQuery(function($) {
425          *   // Your code using failsafe $ alias here...
426          * });
427          * @desc Uses both the shortcut for $(document).ready() and the argument
428          * to write failsafe jQuery code using the $ alias, without relying on the
429          * global alias.
430          *
431          * @name ready
432          * @type jQuery
433          * @param Function fn The function to be executed when the DOM is ready.
434          * @cat Events
435          * @see $.noConflict()
436          * @see $(Function)
437          */
438         ready: function(f) {
439                 // If the DOM is already ready
440                 if ( jQuery.isReady )
441                         // Execute the function immediately
442                         f.apply( document, [jQuery] );
443                         
444                 // Otherwise, remember the function for later
445                 else {
446                         // Add the function to the wait list
447                         jQuery.readyList.push( function() { return f.apply(this, [jQuery]) } );
448                 }
449         
450                 return this;
451         }
452 });
453
454 jQuery.extend({
455         /*
456          * All the code that makes DOM Ready work nicely.
457          */
458         isReady: false,
459         readyList: [],
460         
461         // Handle when the DOM is ready
462         ready: function() {
463                 // Make sure that the DOM is not already loaded
464                 if ( !jQuery.isReady ) {
465                         // Remember that the DOM is ready
466                         jQuery.isReady = true;
467                         
468                         // If there are functions bound, to execute
469                         if ( jQuery.readyList ) {
470                                 // Execute all of them
471                                 for ( var i = 0; i < jQuery.readyList.length; i++ )
472                                         jQuery.readyList[i].apply( document );
473                                 
474                                 // Reset the list of functions
475                                 jQuery.readyList = null;
476                         }
477                         // Remove event lisenter to avoid memory leak
478                         if ( jQuery.browser.mozilla || jQuery.browser.opera )
479                                 document.removeEventListener( "DOMContentLoaded", jQuery.ready, false );
480                 }
481         }
482 });
483
484 new function(){
485
486         /**
487          * Bind a function to the scroll event of each matched element.
488          *
489          * @example $("p").scroll( function() { alert("Hello"); } );
490          * @before <p>Hello</p>
491          * @result <p onscroll="alert('Hello');">Hello</p>
492          *
493          * @name scroll
494          * @type jQuery
495          * @param Function fn A function to bind to the scroll event on each of the matched elements.
496          * @cat Events
497          */
498
499         /**
500          * Bind a function to the submit event of each matched element.
501          *
502          * @example $("#myform").submit( function() {
503          *   return $("input", this).val().length > 0;
504          * } );
505          * @before <form id="myform"><input /></form>
506          * @desc Prevents the form submission when the input has no value entered.
507          *
508          * @name submit
509          * @type jQuery
510          * @param Function fn A function to bind to the submit event on each of the matched elements.
511          * @cat Events
512          */
513
514         /**
515          * Trigger the submit event of each matched element. This causes all of the functions
516          * that have been bound to thet submit event to be executed.
517          *
518          * Note: This does not execute the submit method of the form element! If you need to
519          * submit the form via code, you have to use the DOM method, eg. $("form")[0].submit();
520          *
521          * @example $("form").submit();
522          * @desc Triggers all submit events registered for forms, but does not submit the form
523          *
524          * @name submit
525          * @type jQuery
526          * @cat Events
527          */
528
529         /**
530          * Bind a function to the focus event of each matched element.
531          *
532          * @example $("p").focus( function() { alert("Hello"); } );
533          * @before <p>Hello</p>
534          * @result <p onfocus="alert('Hello');">Hello</p>
535          *
536          * @name focus
537          * @type jQuery
538          * @param Function fn A function to bind to the focus event on each of the matched elements.
539          * @cat Events
540          */
541
542         /**
543          * Trigger the focus event of each matched element. This causes all of the functions
544          * that have been bound to thet focus event to be executed.
545          *
546          * Note: This does not execute the focus method of the underlying elements! If you need to
547          * focus an element via code, you have to use the DOM method, eg. $("#myinput")[0].focus();
548          *
549          * @example $("p").focus();
550          * @before <p onfocus="alert('Hello');">Hello</p>
551          * @result alert('Hello');
552          *
553          * @name focus
554          * @type jQuery
555          * @cat Events
556          */
557
558         /**
559          * Bind a function to the keydown event of each matched element.
560          *
561          * @example $("p").keydown( function() { alert("Hello"); } );
562          * @before <p>Hello</p>
563          * @result <p onkeydown="alert('Hello');">Hello</p>
564          *
565          * @name keydown
566          * @type jQuery
567          * @param Function fn A function to bind to the keydown event on each of the matched elements.
568          * @cat Events
569          */
570
571         /**
572          * Bind a function to the dblclick event of each matched element.
573          *
574          * @example $("p").dblclick( function() { alert("Hello"); } );
575          * @before <p>Hello</p>
576          * @result <p ondblclick="alert('Hello');">Hello</p>
577          *
578          * @name dblclick
579          * @type jQuery
580          * @param Function fn A function to bind to the dblclick event on each of the matched elements.
581          * @cat Events
582          */
583
584         /**
585          * Bind a function to the keypress event of each matched element.
586          *
587          * @example $("p").keypress( function() { alert("Hello"); } );
588          * @before <p>Hello</p>
589          * @result <p onkeypress="alert('Hello');">Hello</p>
590          *
591          * @name keypress
592          * @type jQuery
593          * @param Function fn A function to bind to the keypress event on each of the matched elements.
594          * @cat Events
595          */
596
597         /**
598          * Bind a function to the error event of each matched element.
599          *
600          * @example $("p").error( function() { alert("Hello"); } );
601          * @before <p>Hello</p>
602          * @result <p onerror="alert('Hello');">Hello</p>
603          *
604          * @name error
605          * @type jQuery
606          * @param Function fn A function to bind to the error event on each of the matched elements.
607          * @cat Events
608          */
609
610         /**
611          * Bind a function to the blur event of each matched element.
612          *
613          * @example $("p").blur( function() { alert("Hello"); } );
614          * @before <p>Hello</p>
615          * @result <p onblur="alert('Hello');">Hello</p>
616          *
617          * @name blur
618          * @type jQuery
619          * @param Function fn A function to bind to the blur event on each of the matched elements.
620          * @cat Events
621          */
622
623         /**
624          * Trigger the blur event of each matched element. This causes all of the functions
625          * that have been bound to thet blur event to be executed.
626          *
627          * Note: This does not execute the blur method of the underlying elements! If you need to
628          * blur an element via code, you have to use the DOM method, eg. $("#myinput")[0].blur();
629          *
630          * @example $("p").blur();
631          * @before <p onblur="alert('Hello');">Hello</p>
632          * @result alert('Hello');
633          *
634          * @name blur
635          * @type jQuery
636          * @cat Events
637          */
638
639         /**
640          * Bind a function to the load event of each matched element.
641          *
642          * @example $("p").load( function() { alert("Hello"); } );
643          * @before <p>Hello</p>
644          * @result <p onload="alert('Hello');">Hello</p>
645          *
646          * @name load
647          * @type jQuery
648          * @param Function fn A function to bind to the load event on each of the matched elements.
649          * @cat Events
650          */
651
652         /**
653          * Bind a function to the select event of each matched element.
654          *
655          * @example $("p").select( function() { alert("Hello"); } );
656          * @before <p>Hello</p>
657          * @result <p onselect="alert('Hello');">Hello</p>
658          *
659          * @name select
660          * @type jQuery
661          * @param Function fn A function to bind to the select event on each of the matched elements.
662          * @cat Events
663          */
664
665         /**
666          * Trigger the select event of each matched element. This causes all of the functions
667          * that have been bound to thet select event to be executed.
668          *
669          * @example $("p").select();
670          * @before <p onselect="alert('Hello');">Hello</p>
671          * @result alert('Hello');
672          *
673          * @name select
674          * @type jQuery
675          * @cat Events
676          */
677
678         /**
679          * Bind a function to the mouseup event of each matched element.
680          *
681          * @example $("p").mouseup( function() { alert("Hello"); } );
682          * @before <p>Hello</p>
683          * @result <p onmouseup="alert('Hello');">Hello</p>
684          *
685          * @name mouseup
686          * @type jQuery
687          * @param Function fn A function to bind to the mouseup event on each of the matched elements.
688          * @cat Events
689          */
690
691         /**
692          * Bind a function to the unload event of each matched element.
693          *
694          * @example $("p").unload( function() { alert("Hello"); } );
695          * @before <p>Hello</p>
696          * @result <p onunload="alert('Hello');">Hello</p>
697          *
698          * @name unload
699          * @type jQuery
700          * @param Function fn A function to bind to the unload event on each of the matched elements.
701          * @cat Events
702          */
703
704         /**
705          * Bind a function to the change event of each matched element.
706          *
707          * @example $("p").change( function() { alert("Hello"); } );
708          * @before <p>Hello</p>
709          * @result <p onchange="alert('Hello');">Hello</p>
710          *
711          * @name change
712          * @type jQuery
713          * @param Function fn A function to bind to the change event on each of the matched elements.
714          * @cat Events
715          */
716
717         /**
718          * Bind a function to the mouseout event of each matched element.
719          *
720          * @example $("p").mouseout( function() { alert("Hello"); } );
721          * @before <p>Hello</p>
722          * @result <p onmouseout="alert('Hello');">Hello</p>
723          *
724          * @name mouseout
725          * @type jQuery
726          * @param Function fn A function to bind to the mouseout event on each of the matched elements.
727          * @cat Events
728          */
729
730         /**
731          * Bind a function to the keyup event of each matched element.
732          *
733          * @example $("p").keyup( function() { alert("Hello"); } );
734          * @before <p>Hello</p>
735          * @result <p onkeyup="alert('Hello');">Hello</p>
736          *
737          * @name keyup
738          * @type jQuery
739          * @param Function fn A function to bind to the keyup event on each of the matched elements.
740          * @cat Events
741          */
742
743         /**
744          * Bind a function to the click event of each matched element.
745          *
746          * @example $("p").click( function() { alert("Hello"); } );
747          * @before <p>Hello</p>
748          * @result <p onclick="alert('Hello');">Hello</p>
749          *
750          * @name click
751          * @type jQuery
752          * @param Function fn A function to bind to the click event on each of the matched elements.
753          * @cat Events
754          */
755
756         /**
757          * Trigger the click event of each matched element. This causes all of the functions
758          * that have been bound to thet click event to be executed.
759          *
760          * @example $("p").click();
761          * @before <p onclick="alert('Hello');">Hello</p>
762          * @result alert('Hello');
763          *
764          * @name click
765          * @type jQuery
766          * @cat Events
767          */
768
769         /**
770          * Bind a function to the resize event of each matched element.
771          *
772          * @example $("p").resize( function() { alert("Hello"); } );
773          * @before <p>Hello</p>
774          * @result <p onresize="alert('Hello');">Hello</p>
775          *
776          * @name resize
777          * @type jQuery
778          * @param Function fn A function to bind to the resize event on each of the matched elements.
779          * @cat Events
780          */
781
782         /**
783          * Bind a function to the mousemove event of each matched element.
784          *
785          * @example $("p").mousemove( function() { alert("Hello"); } );
786          * @before <p>Hello</p>
787          * @result <p onmousemove="alert('Hello');">Hello</p>
788          *
789          * @name mousemove
790          * @type jQuery
791          * @param Function fn A function to bind to the mousemove event on each of the matched elements.
792          * @cat Events
793          */
794
795         /**
796          * Bind a function to the mousedown event of each matched element.
797          *
798          * @example $("p").mousedown( function() { alert("Hello"); } );
799          * @before <p>Hello</p>
800          * @result <p onmousedown="alert('Hello');">Hello</p>
801          *
802          * @name mousedown
803          * @type jQuery
804          * @param Function fn A function to bind to the mousedown event on each of the matched elements.
805          * @cat Events
806          */
807          
808         /**
809          * Bind a function to the mouseover event of each matched element.
810          *
811          * @example $("p").mouseover( function() { alert("Hello"); } );
812          * @before <p>Hello</p>
813          * @result <p onmouseover="alert('Hello');">Hello</p>
814          *
815          * @name mouseover
816          * @type jQuery
817          * @param Function fn A function to bind to the mousedown event on each of the matched elements.
818          * @cat Events
819          */
820         jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
821                 "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + 
822                 "submit,keydown,keypress,keyup,error").split(","), function(i,o){
823                 
824                 // Handle event binding
825                 jQuery.fn[o] = function(f){
826                         return f ? this.bind(o, f) : this.trigger(o);
827                 };
828                         
829         });
830         
831         // If Mozilla is used
832         if ( jQuery.browser.mozilla || jQuery.browser.opera )
833                 // Use the handy event callback
834                 document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
835         
836         // If IE is used, use the excellent hack by Matthias Miller
837         // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
838         else if ( jQuery.browser.msie ) {
839         
840                 // Only works if you document.write() it
841                 document.write("<scr" + "ipt id=__ie_init defer=true " + 
842                         "src=//:><\/script>");
843         
844                 // Use the defer script hack
845                 var script = document.getElementById("__ie_init");
846                 
847                 // script does not exist if jQuery is loaded dynamically
848                 if ( script ) 
849                         script.onreadystatechange = function() {
850                                 if ( this.readyState != "complete" ) return;
851                                 this.parentNode.removeChild( this );
852                                 jQuery.ready();
853                         };
854         
855                 // Clear from memory
856                 script = null;
857         
858         // If Safari  is used
859         } else if ( jQuery.browser.safari )
860                 // Continually check to see if the document.readyState is valid
861                 jQuery.safariTimer = setInterval(function(){
862                         // loaded and complete are both valid states
863                         if ( document.readyState == "loaded" || 
864                                 document.readyState == "complete" ) {
865         
866                                 // If either one are found, remove the timer
867                                 clearInterval( jQuery.safariTimer );
868                                 jQuery.safariTimer = null;
869         
870                                 // and execute any waiting functions
871                                 jQuery.ready();
872                         }
873                 }, 10); 
874
875         // A fallback to window.onload, that will always work
876         jQuery.event.add( window, "load", jQuery.ready );
877         
878 };
879
880 // Clean up after IE to avoid memory leaks
881 if (jQuery.browser.msie)
882         jQuery(window).one("unload", function() {
883                 var global = jQuery.event.global;
884                 for ( var type in global ) {
885                         var els = global[type], i = els.length;
886                         if ( i && type != 'unload' )
887                                 do
888                                         jQuery.event.remove(els[i-1], type);
889                                 while (--i);
890                 }
891         });