You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

trigger.js 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. define( [
  2. "../core",
  3. "../var/document",
  4. "../data/var/dataPriv",
  5. "../data/var/acceptData",
  6. "../var/hasOwn",
  7. "../event"
  8. ], function( jQuery, document, dataPriv, acceptData, hasOwn ) {
  9. var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
  10. jQuery.extend( jQuery.event, {
  11. trigger: function( event, data, elem, onlyHandlers ) {
  12. var i, cur, tmp, bubbleType, ontype, handle, special,
  13. eventPath = [ elem || document ],
  14. type = hasOwn.call( event, "type" ) ? event.type : event,
  15. namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
  16. cur = tmp = elem = elem || document;
  17. // Don't do events on text and comment nodes
  18. if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
  19. return;
  20. }
  21. // focus/blur morphs to focusin/out; ensure we're not firing them right now
  22. if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
  23. return;
  24. }
  25. if ( type.indexOf( "." ) > -1 ) {
  26. // Namespaced trigger; create a regexp to match event type in handle()
  27. namespaces = type.split( "." );
  28. type = namespaces.shift();
  29. namespaces.sort();
  30. }
  31. ontype = type.indexOf( ":" ) < 0 && "on" + type;
  32. // Caller can pass in a jQuery.Event object, Object, or just an event type string
  33. event = event[ jQuery.expando ] ?
  34. event :
  35. new jQuery.Event( type, typeof event === "object" && event );
  36. // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
  37. event.isTrigger = onlyHandlers ? 2 : 3;
  38. event.namespace = namespaces.join( "." );
  39. event.rnamespace = event.namespace ?
  40. new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
  41. null;
  42. // Clean up the event in case it is being reused
  43. event.result = undefined;
  44. if ( !event.target ) {
  45. event.target = elem;
  46. }
  47. // Clone any incoming data and prepend the event, creating the handler arg list
  48. data = data == null ?
  49. [ event ] :
  50. jQuery.makeArray( data, [ event ] );
  51. // Allow special events to draw outside the lines
  52. special = jQuery.event.special[ type ] || {};
  53. if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
  54. return;
  55. }
  56. // Determine event propagation path in advance, per W3C events spec (#9951)
  57. // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
  58. if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
  59. bubbleType = special.delegateType || type;
  60. if ( !rfocusMorph.test( bubbleType + type ) ) {
  61. cur = cur.parentNode;
  62. }
  63. for ( ; cur; cur = cur.parentNode ) {
  64. eventPath.push( cur );
  65. tmp = cur;
  66. }
  67. // Only add window if we got to document (e.g., not plain obj or detached DOM)
  68. if ( tmp === ( elem.ownerDocument || document ) ) {
  69. eventPath.push( tmp.defaultView || tmp.parentWindow || window );
  70. }
  71. }
  72. // Fire handlers on the event path
  73. i = 0;
  74. while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
  75. event.type = i > 1 ?
  76. bubbleType :
  77. special.bindType || type;
  78. // jQuery handler
  79. handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
  80. dataPriv.get( cur, "handle" );
  81. if ( handle ) {
  82. handle.apply( cur, data );
  83. }
  84. // Native handler
  85. handle = ontype && cur[ ontype ];
  86. if ( handle && handle.apply && acceptData( cur ) ) {
  87. event.result = handle.apply( cur, data );
  88. if ( event.result === false ) {
  89. event.preventDefault();
  90. }
  91. }
  92. }
  93. event.type = type;
  94. // If nobody prevented the default action, do it now
  95. if ( !onlyHandlers && !event.isDefaultPrevented() ) {
  96. if ( ( !special._default ||
  97. special._default.apply( eventPath.pop(), data ) === false ) &&
  98. acceptData( elem ) ) {
  99. // Call a native DOM method on the target with the same name name as the event.
  100. // Don't do default actions on window, that's where global variables be (#6170)
  101. if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
  102. // Don't re-trigger an onFOO event when we call its FOO() method
  103. tmp = elem[ ontype ];
  104. if ( tmp ) {
  105. elem[ ontype ] = null;
  106. }
  107. // Prevent re-triggering of the same event, since we already bubbled it above
  108. jQuery.event.triggered = type;
  109. elem[ type ]();
  110. jQuery.event.triggered = undefined;
  111. if ( tmp ) {
  112. elem[ ontype ] = tmp;
  113. }
  114. }
  115. }
  116. }
  117. return event.result;
  118. },
  119. // Piggyback on a donor event to simulate a different one
  120. // Used only for `focus(in | out)` events
  121. simulate: function( type, elem, event ) {
  122. var e = jQuery.extend(
  123. new jQuery.Event(),
  124. event,
  125. {
  126. type: type,
  127. isSimulated: true
  128. }
  129. );
  130. jQuery.event.trigger( e, null, elem );
  131. }
  132. } );
  133. jQuery.fn.extend( {
  134. trigger: function( type, data ) {
  135. return this.each( function() {
  136. jQuery.event.trigger( type, data, this );
  137. } );
  138. },
  139. triggerHandler: function( type, data ) {
  140. var elem = this[ 0 ];
  141. if ( elem ) {
  142. return jQuery.event.trigger( type, data, elem, true );
  143. }
  144. }
  145. } );
  146. return jQuery;
  147. } );