Mercurial > nebulaweb3
comparison default/node_modules/jquery/src/event.js @ 0:1d038bc9b3d2 default tip
Up:default
author | Liny <dev@neowd.com> |
---|---|
date | Sat, 31 May 2025 09:21:51 +0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1d038bc9b3d2 |
---|---|
1 define( [ | |
2 "./core", | |
3 "./var/document", | |
4 "./var/documentElement", | |
5 "./var/isFunction", | |
6 "./var/rnothtmlwhite", | |
7 "./var/slice", | |
8 "./data/var/dataPriv", | |
9 "./core/nodeName", | |
10 | |
11 "./core/init", | |
12 "./selector" | |
13 ], function( jQuery, document, documentElement, isFunction, rnothtmlwhite, | |
14 slice, dataPriv, nodeName ) { | |
15 | |
16 "use strict"; | |
17 | |
18 var | |
19 rkeyEvent = /^key/, | |
20 rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, | |
21 rtypenamespace = /^([^.]*)(?:\.(.+)|)/; | |
22 | |
23 function returnTrue() { | |
24 return true; | |
25 } | |
26 | |
27 function returnFalse() { | |
28 return false; | |
29 } | |
30 | |
31 // Support: IE <=9 only | |
32 // See #13393 for more info | |
33 function safeActiveElement() { | |
34 try { | |
35 return document.activeElement; | |
36 } catch ( err ) { } | |
37 } | |
38 | |
39 function on( elem, types, selector, data, fn, one ) { | |
40 var origFn, type; | |
41 | |
42 // Types can be a map of types/handlers | |
43 if ( typeof types === "object" ) { | |
44 | |
45 // ( types-Object, selector, data ) | |
46 if ( typeof selector !== "string" ) { | |
47 | |
48 // ( types-Object, data ) | |
49 data = data || selector; | |
50 selector = undefined; | |
51 } | |
52 for ( type in types ) { | |
53 on( elem, type, selector, data, types[ type ], one ); | |
54 } | |
55 return elem; | |
56 } | |
57 | |
58 if ( data == null && fn == null ) { | |
59 | |
60 // ( types, fn ) | |
61 fn = selector; | |
62 data = selector = undefined; | |
63 } else if ( fn == null ) { | |
64 if ( typeof selector === "string" ) { | |
65 | |
66 // ( types, selector, fn ) | |
67 fn = data; | |
68 data = undefined; | |
69 } else { | |
70 | |
71 // ( types, data, fn ) | |
72 fn = data; | |
73 data = selector; | |
74 selector = undefined; | |
75 } | |
76 } | |
77 if ( fn === false ) { | |
78 fn = returnFalse; | |
79 } else if ( !fn ) { | |
80 return elem; | |
81 } | |
82 | |
83 if ( one === 1 ) { | |
84 origFn = fn; | |
85 fn = function( event ) { | |
86 | |
87 // Can use an empty set, since event contains the info | |
88 jQuery().off( event ); | |
89 return origFn.apply( this, arguments ); | |
90 }; | |
91 | |
92 // Use same guid so caller can remove using origFn | |
93 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); | |
94 } | |
95 return elem.each( function() { | |
96 jQuery.event.add( this, types, fn, data, selector ); | |
97 } ); | |
98 } | |
99 | |
100 /* | |
101 * Helper functions for managing events -- not part of the public interface. | |
102 * Props to Dean Edwards' addEvent library for many of the ideas. | |
103 */ | |
104 jQuery.event = { | |
105 | |
106 global: {}, | |
107 | |
108 add: function( elem, types, handler, data, selector ) { | |
109 | |
110 var handleObjIn, eventHandle, tmp, | |
111 events, t, handleObj, | |
112 special, handlers, type, namespaces, origType, | |
113 elemData = dataPriv.get( elem ); | |
114 | |
115 // Don't attach events to noData or text/comment nodes (but allow plain objects) | |
116 if ( !elemData ) { | |
117 return; | |
118 } | |
119 | |
120 // Caller can pass in an object of custom data in lieu of the handler | |
121 if ( handler.handler ) { | |
122 handleObjIn = handler; | |
123 handler = handleObjIn.handler; | |
124 selector = handleObjIn.selector; | |
125 } | |
126 | |
127 // Ensure that invalid selectors throw exceptions at attach time | |
128 // Evaluate against documentElement in case elem is a non-element node (e.g., document) | |
129 if ( selector ) { | |
130 jQuery.find.matchesSelector( documentElement, selector ); | |
131 } | |
132 | |
133 // Make sure that the handler has a unique ID, used to find/remove it later | |
134 if ( !handler.guid ) { | |
135 handler.guid = jQuery.guid++; | |
136 } | |
137 | |
138 // Init the element's event structure and main handler, if this is the first | |
139 if ( !( events = elemData.events ) ) { | |
140 events = elemData.events = {}; | |
141 } | |
142 if ( !( eventHandle = elemData.handle ) ) { | |
143 eventHandle = elemData.handle = function( e ) { | |
144 | |
145 // Discard the second event of a jQuery.event.trigger() and | |
146 // when an event is called after a page has unloaded | |
147 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? | |
148 jQuery.event.dispatch.apply( elem, arguments ) : undefined; | |
149 }; | |
150 } | |
151 | |
152 // Handle multiple events separated by a space | |
153 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; | |
154 t = types.length; | |
155 while ( t-- ) { | |
156 tmp = rtypenamespace.exec( types[ t ] ) || []; | |
157 type = origType = tmp[ 1 ]; | |
158 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); | |
159 | |
160 // There *must* be a type, no attaching namespace-only handlers | |
161 if ( !type ) { | |
162 continue; | |
163 } | |
164 | |
165 // If event changes its type, use the special event handlers for the changed type | |
166 special = jQuery.event.special[ type ] || {}; | |
167 | |
168 // If selector defined, determine special event api type, otherwise given type | |
169 type = ( selector ? special.delegateType : special.bindType ) || type; | |
170 | |
171 // Update special based on newly reset type | |
172 special = jQuery.event.special[ type ] || {}; | |
173 | |
174 // handleObj is passed to all event handlers | |
175 handleObj = jQuery.extend( { | |
176 type: type, | |
177 origType: origType, | |
178 data: data, | |
179 handler: handler, | |
180 guid: handler.guid, | |
181 selector: selector, | |
182 needsContext: selector && jQuery.expr.match.needsContext.test( selector ), | |
183 namespace: namespaces.join( "." ) | |
184 }, handleObjIn ); | |
185 | |
186 // Init the event handler queue if we're the first | |
187 if ( !( handlers = events[ type ] ) ) { | |
188 handlers = events[ type ] = []; | |
189 handlers.delegateCount = 0; | |
190 | |
191 // Only use addEventListener if the special events handler returns false | |
192 if ( !special.setup || | |
193 special.setup.call( elem, data, namespaces, eventHandle ) === false ) { | |
194 | |
195 if ( elem.addEventListener ) { | |
196 elem.addEventListener( type, eventHandle ); | |
197 } | |
198 } | |
199 } | |
200 | |
201 if ( special.add ) { | |
202 special.add.call( elem, handleObj ); | |
203 | |
204 if ( !handleObj.handler.guid ) { | |
205 handleObj.handler.guid = handler.guid; | |
206 } | |
207 } | |
208 | |
209 // Add to the element's handler list, delegates in front | |
210 if ( selector ) { | |
211 handlers.splice( handlers.delegateCount++, 0, handleObj ); | |
212 } else { | |
213 handlers.push( handleObj ); | |
214 } | |
215 | |
216 // Keep track of which events have ever been used, for event optimization | |
217 jQuery.event.global[ type ] = true; | |
218 } | |
219 | |
220 }, | |
221 | |
222 // Detach an event or set of events from an element | |
223 remove: function( elem, types, handler, selector, mappedTypes ) { | |
224 | |
225 var j, origCount, tmp, | |
226 events, t, handleObj, | |
227 special, handlers, type, namespaces, origType, | |
228 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); | |
229 | |
230 if ( !elemData || !( events = elemData.events ) ) { | |
231 return; | |
232 } | |
233 | |
234 // Once for each type.namespace in types; type may be omitted | |
235 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; | |
236 t = types.length; | |
237 while ( t-- ) { | |
238 tmp = rtypenamespace.exec( types[ t ] ) || []; | |
239 type = origType = tmp[ 1 ]; | |
240 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); | |
241 | |
242 // Unbind all events (on this namespace, if provided) for the element | |
243 if ( !type ) { | |
244 for ( type in events ) { | |
245 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); | |
246 } | |
247 continue; | |
248 } | |
249 | |
250 special = jQuery.event.special[ type ] || {}; | |
251 type = ( selector ? special.delegateType : special.bindType ) || type; | |
252 handlers = events[ type ] || []; | |
253 tmp = tmp[ 2 ] && | |
254 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); | |
255 | |
256 // Remove matching events | |
257 origCount = j = handlers.length; | |
258 while ( j-- ) { | |
259 handleObj = handlers[ j ]; | |
260 | |
261 if ( ( mappedTypes || origType === handleObj.origType ) && | |
262 ( !handler || handler.guid === handleObj.guid ) && | |
263 ( !tmp || tmp.test( handleObj.namespace ) ) && | |
264 ( !selector || selector === handleObj.selector || | |
265 selector === "**" && handleObj.selector ) ) { | |
266 handlers.splice( j, 1 ); | |
267 | |
268 if ( handleObj.selector ) { | |
269 handlers.delegateCount--; | |
270 } | |
271 if ( special.remove ) { | |
272 special.remove.call( elem, handleObj ); | |
273 } | |
274 } | |
275 } | |
276 | |
277 // Remove generic event handler if we removed something and no more handlers exist | |
278 // (avoids potential for endless recursion during removal of special event handlers) | |
279 if ( origCount && !handlers.length ) { | |
280 if ( !special.teardown || | |
281 special.teardown.call( elem, namespaces, elemData.handle ) === false ) { | |
282 | |
283 jQuery.removeEvent( elem, type, elemData.handle ); | |
284 } | |
285 | |
286 delete events[ type ]; | |
287 } | |
288 } | |
289 | |
290 // Remove data and the expando if it's no longer used | |
291 if ( jQuery.isEmptyObject( events ) ) { | |
292 dataPriv.remove( elem, "handle events" ); | |
293 } | |
294 }, | |
295 | |
296 dispatch: function( nativeEvent ) { | |
297 | |
298 // Make a writable jQuery.Event from the native event object | |
299 var event = jQuery.event.fix( nativeEvent ); | |
300 | |
301 var i, j, ret, matched, handleObj, handlerQueue, | |
302 args = new Array( arguments.length ), | |
303 handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], | |
304 special = jQuery.event.special[ event.type ] || {}; | |
305 | |
306 // Use the fix-ed jQuery.Event rather than the (read-only) native event | |
307 args[ 0 ] = event; | |
308 | |
309 for ( i = 1; i < arguments.length; i++ ) { | |
310 args[ i ] = arguments[ i ]; | |
311 } | |
312 | |
313 event.delegateTarget = this; | |
314 | |
315 // Call the preDispatch hook for the mapped type, and let it bail if desired | |
316 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { | |
317 return; | |
318 } | |
319 | |
320 // Determine handlers | |
321 handlerQueue = jQuery.event.handlers.call( this, event, handlers ); | |
322 | |
323 // Run delegates first; they may want to stop propagation beneath us | |
324 i = 0; | |
325 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { | |
326 event.currentTarget = matched.elem; | |
327 | |
328 j = 0; | |
329 while ( ( handleObj = matched.handlers[ j++ ] ) && | |
330 !event.isImmediatePropagationStopped() ) { | |
331 | |
332 // Triggered event must either 1) have no namespace, or 2) have namespace(s) | |
333 // a subset or equal to those in the bound event (both can have no namespace). | |
334 if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { | |
335 | |
336 event.handleObj = handleObj; | |
337 event.data = handleObj.data; | |
338 | |
339 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || | |
340 handleObj.handler ).apply( matched.elem, args ); | |
341 | |
342 if ( ret !== undefined ) { | |
343 if ( ( event.result = ret ) === false ) { | |
344 event.preventDefault(); | |
345 event.stopPropagation(); | |
346 } | |
347 } | |
348 } | |
349 } | |
350 } | |
351 | |
352 // Call the postDispatch hook for the mapped type | |
353 if ( special.postDispatch ) { | |
354 special.postDispatch.call( this, event ); | |
355 } | |
356 | |
357 return event.result; | |
358 }, | |
359 | |
360 handlers: function( event, handlers ) { | |
361 var i, handleObj, sel, matchedHandlers, matchedSelectors, | |
362 handlerQueue = [], | |
363 delegateCount = handlers.delegateCount, | |
364 cur = event.target; | |
365 | |
366 // Find delegate handlers | |
367 if ( delegateCount && | |
368 | |
369 // Support: IE <=9 | |
370 // Black-hole SVG <use> instance trees (trac-13180) | |
371 cur.nodeType && | |
372 | |
373 // Support: Firefox <=42 | |
374 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) | |
375 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click | |
376 // Support: IE 11 only | |
377 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) | |
378 !( event.type === "click" && event.button >= 1 ) ) { | |
379 | |
380 for ( ; cur !== this; cur = cur.parentNode || this ) { | |
381 | |
382 // Don't check non-elements (#13208) | |
383 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) | |
384 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { | |
385 matchedHandlers = []; | |
386 matchedSelectors = {}; | |
387 for ( i = 0; i < delegateCount; i++ ) { | |
388 handleObj = handlers[ i ]; | |
389 | |
390 // Don't conflict with Object.prototype properties (#13203) | |
391 sel = handleObj.selector + " "; | |
392 | |
393 if ( matchedSelectors[ sel ] === undefined ) { | |
394 matchedSelectors[ sel ] = handleObj.needsContext ? | |
395 jQuery( sel, this ).index( cur ) > -1 : | |
396 jQuery.find( sel, this, null, [ cur ] ).length; | |
397 } | |
398 if ( matchedSelectors[ sel ] ) { | |
399 matchedHandlers.push( handleObj ); | |
400 } | |
401 } | |
402 if ( matchedHandlers.length ) { | |
403 handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); | |
404 } | |
405 } | |
406 } | |
407 } | |
408 | |
409 // Add the remaining (directly-bound) handlers | |
410 cur = this; | |
411 if ( delegateCount < handlers.length ) { | |
412 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); | |
413 } | |
414 | |
415 return handlerQueue; | |
416 }, | |
417 | |
418 addProp: function( name, hook ) { | |
419 Object.defineProperty( jQuery.Event.prototype, name, { | |
420 enumerable: true, | |
421 configurable: true, | |
422 | |
423 get: isFunction( hook ) ? | |
424 function() { | |
425 if ( this.originalEvent ) { | |
426 return hook( this.originalEvent ); | |
427 } | |
428 } : | |
429 function() { | |
430 if ( this.originalEvent ) { | |
431 return this.originalEvent[ name ]; | |
432 } | |
433 }, | |
434 | |
435 set: function( value ) { | |
436 Object.defineProperty( this, name, { | |
437 enumerable: true, | |
438 configurable: true, | |
439 writable: true, | |
440 value: value | |
441 } ); | |
442 } | |
443 } ); | |
444 }, | |
445 | |
446 fix: function( originalEvent ) { | |
447 return originalEvent[ jQuery.expando ] ? | |
448 originalEvent : | |
449 new jQuery.Event( originalEvent ); | |
450 }, | |
451 | |
452 special: { | |
453 load: { | |
454 | |
455 // Prevent triggered image.load events from bubbling to window.load | |
456 noBubble: true | |
457 }, | |
458 focus: { | |
459 | |
460 // Fire native event if possible so blur/focus sequence is correct | |
461 trigger: function() { | |
462 if ( this !== safeActiveElement() && this.focus ) { | |
463 this.focus(); | |
464 return false; | |
465 } | |
466 }, | |
467 delegateType: "focusin" | |
468 }, | |
469 blur: { | |
470 trigger: function() { | |
471 if ( this === safeActiveElement() && this.blur ) { | |
472 this.blur(); | |
473 return false; | |
474 } | |
475 }, | |
476 delegateType: "focusout" | |
477 }, | |
478 click: { | |
479 | |
480 // For checkbox, fire native event so checked state will be right | |
481 trigger: function() { | |
482 if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) { | |
483 this.click(); | |
484 return false; | |
485 } | |
486 }, | |
487 | |
488 // For cross-browser consistency, don't fire native .click() on links | |
489 _default: function( event ) { | |
490 return nodeName( event.target, "a" ); | |
491 } | |
492 }, | |
493 | |
494 beforeunload: { | |
495 postDispatch: function( event ) { | |
496 | |
497 // Support: Firefox 20+ | |
498 // Firefox doesn't alert if the returnValue field is not set. | |
499 if ( event.result !== undefined && event.originalEvent ) { | |
500 event.originalEvent.returnValue = event.result; | |
501 } | |
502 } | |
503 } | |
504 } | |
505 }; | |
506 | |
507 jQuery.removeEvent = function( elem, type, handle ) { | |
508 | |
509 // This "if" is needed for plain objects | |
510 if ( elem.removeEventListener ) { | |
511 elem.removeEventListener( type, handle ); | |
512 } | |
513 }; | |
514 | |
515 jQuery.Event = function( src, props ) { | |
516 | |
517 // Allow instantiation without the 'new' keyword | |
518 if ( !( this instanceof jQuery.Event ) ) { | |
519 return new jQuery.Event( src, props ); | |
520 } | |
521 | |
522 // Event object | |
523 if ( src && src.type ) { | |
524 this.originalEvent = src; | |
525 this.type = src.type; | |
526 | |
527 // Events bubbling up the document may have been marked as prevented | |
528 // by a handler lower down the tree; reflect the correct value. | |
529 this.isDefaultPrevented = src.defaultPrevented || | |
530 src.defaultPrevented === undefined && | |
531 | |
532 // Support: Android <=2.3 only | |
533 src.returnValue === false ? | |
534 returnTrue : | |
535 returnFalse; | |
536 | |
537 // Create target properties | |
538 // Support: Safari <=6 - 7 only | |
539 // Target should not be a text node (#504, #13143) | |
540 this.target = ( src.target && src.target.nodeType === 3 ) ? | |
541 src.target.parentNode : | |
542 src.target; | |
543 | |
544 this.currentTarget = src.currentTarget; | |
545 this.relatedTarget = src.relatedTarget; | |
546 | |
547 // Event type | |
548 } else { | |
549 this.type = src; | |
550 } | |
551 | |
552 // Put explicitly provided properties onto the event object | |
553 if ( props ) { | |
554 jQuery.extend( this, props ); | |
555 } | |
556 | |
557 // Create a timestamp if incoming event doesn't have one | |
558 this.timeStamp = src && src.timeStamp || Date.now(); | |
559 | |
560 // Mark it as fixed | |
561 this[ jQuery.expando ] = true; | |
562 }; | |
563 | |
564 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding | |
565 // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html | |
566 jQuery.Event.prototype = { | |
567 constructor: jQuery.Event, | |
568 isDefaultPrevented: returnFalse, | |
569 isPropagationStopped: returnFalse, | |
570 isImmediatePropagationStopped: returnFalse, | |
571 isSimulated: false, | |
572 | |
573 preventDefault: function() { | |
574 var e = this.originalEvent; | |
575 | |
576 this.isDefaultPrevented = returnTrue; | |
577 | |
578 if ( e && !this.isSimulated ) { | |
579 e.preventDefault(); | |
580 } | |
581 }, | |
582 stopPropagation: function() { | |
583 var e = this.originalEvent; | |
584 | |
585 this.isPropagationStopped = returnTrue; | |
586 | |
587 if ( e && !this.isSimulated ) { | |
588 e.stopPropagation(); | |
589 } | |
590 }, | |
591 stopImmediatePropagation: function() { | |
592 var e = this.originalEvent; | |
593 | |
594 this.isImmediatePropagationStopped = returnTrue; | |
595 | |
596 if ( e && !this.isSimulated ) { | |
597 e.stopImmediatePropagation(); | |
598 } | |
599 | |
600 this.stopPropagation(); | |
601 } | |
602 }; | |
603 | |
604 // Includes all common event props including KeyEvent and MouseEvent specific props | |
605 jQuery.each( { | |
606 altKey: true, | |
607 bubbles: true, | |
608 cancelable: true, | |
609 changedTouches: true, | |
610 ctrlKey: true, | |
611 detail: true, | |
612 eventPhase: true, | |
613 metaKey: true, | |
614 pageX: true, | |
615 pageY: true, | |
616 shiftKey: true, | |
617 view: true, | |
618 "char": true, | |
619 charCode: true, | |
620 key: true, | |
621 keyCode: true, | |
622 button: true, | |
623 buttons: true, | |
624 clientX: true, | |
625 clientY: true, | |
626 offsetX: true, | |
627 offsetY: true, | |
628 pointerId: true, | |
629 pointerType: true, | |
630 screenX: true, | |
631 screenY: true, | |
632 targetTouches: true, | |
633 toElement: true, | |
634 touches: true, | |
635 | |
636 which: function( event ) { | |
637 var button = event.button; | |
638 | |
639 // Add which for key events | |
640 if ( event.which == null && rkeyEvent.test( event.type ) ) { | |
641 return event.charCode != null ? event.charCode : event.keyCode; | |
642 } | |
643 | |
644 // Add which for click: 1 === left; 2 === middle; 3 === right | |
645 if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { | |
646 if ( button & 1 ) { | |
647 return 1; | |
648 } | |
649 | |
650 if ( button & 2 ) { | |
651 return 3; | |
652 } | |
653 | |
654 if ( button & 4 ) { | |
655 return 2; | |
656 } | |
657 | |
658 return 0; | |
659 } | |
660 | |
661 return event.which; | |
662 } | |
663 }, jQuery.event.addProp ); | |
664 | |
665 // Create mouseenter/leave events using mouseover/out and event-time checks | |
666 // so that event delegation works in jQuery. | |
667 // Do the same for pointerenter/pointerleave and pointerover/pointerout | |
668 // | |
669 // Support: Safari 7 only | |
670 // Safari sends mouseenter too often; see: | |
671 // https://bugs.chromium.org/p/chromium/issues/detail?id=470258 | |
672 // for the description of the bug (it existed in older Chrome versions as well). | |
673 jQuery.each( { | |
674 mouseenter: "mouseover", | |
675 mouseleave: "mouseout", | |
676 pointerenter: "pointerover", | |
677 pointerleave: "pointerout" | |
678 }, function( orig, fix ) { | |
679 jQuery.event.special[ orig ] = { | |
680 delegateType: fix, | |
681 bindType: fix, | |
682 | |
683 handle: function( event ) { | |
684 var ret, | |
685 target = this, | |
686 related = event.relatedTarget, | |
687 handleObj = event.handleObj; | |
688 | |
689 // For mouseenter/leave call the handler if related is outside the target. | |
690 // NB: No relatedTarget if the mouse left/entered the browser window | |
691 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { | |
692 event.type = handleObj.origType; | |
693 ret = handleObj.handler.apply( this, arguments ); | |
694 event.type = fix; | |
695 } | |
696 return ret; | |
697 } | |
698 }; | |
699 } ); | |
700 | |
701 jQuery.fn.extend( { | |
702 | |
703 on: function( types, selector, data, fn ) { | |
704 return on( this, types, selector, data, fn ); | |
705 }, | |
706 one: function( types, selector, data, fn ) { | |
707 return on( this, types, selector, data, fn, 1 ); | |
708 }, | |
709 off: function( types, selector, fn ) { | |
710 var handleObj, type; | |
711 if ( types && types.preventDefault && types.handleObj ) { | |
712 | |
713 // ( event ) dispatched jQuery.Event | |
714 handleObj = types.handleObj; | |
715 jQuery( types.delegateTarget ).off( | |
716 handleObj.namespace ? | |
717 handleObj.origType + "." + handleObj.namespace : | |
718 handleObj.origType, | |
719 handleObj.selector, | |
720 handleObj.handler | |
721 ); | |
722 return this; | |
723 } | |
724 if ( typeof types === "object" ) { | |
725 | |
726 // ( types-object [, selector] ) | |
727 for ( type in types ) { | |
728 this.off( type, selector, types[ type ] ); | |
729 } | |
730 return this; | |
731 } | |
732 if ( selector === false || typeof selector === "function" ) { | |
733 | |
734 // ( types [, fn] ) | |
735 fn = selector; | |
736 selector = undefined; | |
737 } | |
738 if ( fn === false ) { | |
739 fn = returnFalse; | |
740 } | |
741 return this.each( function() { | |
742 jQuery.event.remove( this, types, fn, selector ); | |
743 } ); | |
744 } | |
745 } ); | |
746 | |
747 return jQuery; | |
748 } ); |