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