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