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