@@ -261,17 +261,7 @@ jQuery.event = {
261
261
// Event object or event type
262
262
var type = event . type || event ,
263
263
namespaces = [ ] ,
264
- cache , exclusive , i , cur , old , ontype , special , doc , eventPath , bubbleType ,
265
- addHandlers = function ( elem , type ) {
266
- // Defer getting handler so we don't waste time in case propagation is stopped
267
- if ( ( jQuery . _data ( elem , "events" ) || { } ) [ type ] ) {
268
- eventPath . push ( { elem : elem , type : type /*, handler: jQuery._data( elem, "handle" ) */ } ) ;
269
- }
270
- // IE doesn't like method names with a colon (#3533, #8272)
271
- if ( ontype && jQuery . acceptData ( elem ) && elem [ ontype ] ) {
272
- eventPath . push ( { elem : elem , type : type , handler : elem [ ontype ] } ) ;
273
- }
274
- } ;
264
+ cache , exclusive , i , cur , old , ontype , special , handle , eventPath , bubbleType ;
275
265
276
266
if ( type . indexOf ( "!" ) >= 0 ) {
277
267
// Exclusive events trigger only for the exact event (no namespaces)
@@ -310,14 +300,14 @@ jQuery.event = {
310
300
// triggerHandler() and global events don't bubble or run the default action
311
301
if ( onlyHandlers || ! elem ) {
312
302
event . preventDefault ( ) ;
313
- event . stopPropagation ( ) ;
314
303
}
315
304
316
305
// Handle a global trigger
317
306
if ( ! elem ) {
318
307
319
308
// TODO: Stop taunting the data cache; remove global events and always attach to document
320
309
cache = jQuery . cache ;
310
+ event . stopPropagation ( ) ;
321
311
for ( i in cache ) {
322
312
if ( cache [ i ] . events && cache [ i ] . events [ type ] ) {
323
313
jQuery . event . trigger ( event , data , cache [ i ] . handle . elem ) ;
@@ -344,23 +334,37 @@ jQuery.event = {
344
334
345
335
// Determine event propagation path in advance, per W3C events spec (#9951)
346
336
// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
347
- // Always fire handlers for the target, even if prop is stopped in advance
348
- eventPath = [ ] ;
349
- addHandlers ( elem , special . bindType || type ) ;
350
- doc = elem . ownerDocument ;
351
- if ( doc && ! special . noBubble && ! jQuery . isWindow ( elem ) & ! event . isPropagationStopped ( ) ) {
337
+ eventPath = [ [ elem , special . bindType || type ] ] ;
338
+ if ( ! onlyHandlers && ! special . noBubble && ! jQuery . isWindow ( elem ) ) {
339
+
352
340
bubbleType = special . delegateType || type ;
341
+ old = null ;
353
342
for ( cur = elem . parentNode ; cur ; cur = cur . parentNode ) {
354
- addHandlers ( cur , bubbleType ) ;
343
+ eventPath . push ( [ cur , bubbleType ] ) ;
344
+ old = cur ;
345
+ }
346
+
347
+ // Only add window if we got to document (e.g., not plain obj or detached DOM)
348
+ if ( old && old === elem . ownerDocument ) {
349
+ eventPath . push ( [ old . defaultView || old . parentWindow || window , bubbleType ] ) ;
355
350
}
356
- addHandlers ( doc . defaultView || doc . parentWindow || window , bubbleType ) ;
357
351
}
358
352
359
- // Bubble up the DOM tree
353
+ // Fire handlers on the event path
360
354
for ( i = 0 ; i < eventPath . length ; i ++ ) {
361
- cur = eventPath [ i ] ;
362
- event . type = cur . type ;
363
- ( cur . handler || jQuery . _data ( cur . elem , "handle" ) ) . apply ( cur . elem , data ) ;
355
+
356
+ cur = eventPath [ i ] [ 0 ] ;
357
+ event . type = eventPath [ i ] [ 1 ] ;
358
+
359
+ handle = ( jQuery . _data ( cur , "events" ) || { } ) [ event . type ] && jQuery . _data ( cur , "handle" ) ;
360
+ if ( handle ) {
361
+ handle . apply ( cur , data ) ;
362
+ }
363
+ handle = ontype && cur [ ontype ] ;
364
+ if ( handle && jQuery . acceptData ( cur ) ) {
365
+ handle . apply ( cur , data ) ;
366
+ }
367
+
364
368
if ( event . isPropagationStopped ( ) ) {
365
369
break ;
366
370
}
0 commit comments