11import Browser from './Browser' ;
2- import { extend , isString , isNil } from './util' ;
2+ import { extend , isString , isNil , UID , isNumber } from './util' ;
33import { stopPropagation } from './util/dom' ;
44/**
55 * This provides methods used for event handling. It's a mixin and not meant to be used directly.
66 * @mixin Eventable
77 */
88
9+ function generateWrapKey ( eventType ) {
10+ return 'Z__' + eventType ;
11+ }
12+
913const Eventable = Base =>
1014
1115 class extends Base {
@@ -38,14 +42,29 @@ const Eventable = Base =>
3842 if ( ! context ) {
3943 context = this ;
4044 }
45+ //检测handler是否被监听过
46+ const isAdd = isNumber ( handler . _id ) ;
47+ handler . _id = UID ( ) ;
4148 let handlerChain ;
4249 for ( let ii = 0 , ll = eventTypes . length ; ii < ll ; ii ++ ) {
4350 evtType = eventTypes [ ii ] ;
51+ const wrapKey = generateWrapKey ( evtType ) ;
52+ if ( handler [ wrapKey ] ) {
53+ handler [ wrapKey ] . _id = handler . _id ;
54+ }
4455 handlerChain = this . _eventMap [ evtType ] ;
4556 if ( ! handlerChain ) {
4657 handlerChain = [ ] ;
4758 this . _eventMap [ evtType ] = handlerChain ;
4859 }
60+ //没有监听过的handler直接入列
61+ if ( ! isAdd ) {
62+ handlerChain . push ( {
63+ handler : handler ,
64+ context : context
65+ } ) ;
66+ continue ;
67+ }
4968 const l = handlerChain . length ;
5069 if ( l > 0 ) {
5170 for ( let i = 0 ; i < l ; i ++ ) {
@@ -127,17 +146,21 @@ const Eventable = Base =>
127146 if ( ! handler ) {
128147 return this ;
129148 }
149+ //没有监听过的handler直接忽略
150+ if ( ! isNumber ( handler . _id ) ) {
151+ return this ;
152+ }
130153 const eventTypes = eventsOff . split ( ' ' ) ;
131154 let eventType , listeners , wrapKey ;
132155 if ( ! context ) {
133156 context = this ;
134157 }
135158 for ( let j = 0 , jl = eventTypes . length ; j < jl ; j ++ ) {
136159 eventType = eventTypes [ j ] . toLowerCase ( ) ;
137- wrapKey = 'Z__' + eventType ;
160+ wrapKey = generateWrapKey ( eventType ) ;
138161 listeners = this . _eventMap [ eventType ] ;
139162 if ( ! listeners ) {
140- return this ;
163+ continue ;
141164 }
142165 for ( let i = listeners . length - 1 ; i >= 0 ; i -- ) {
143166 const listener = listeners [ i ] ;
@@ -245,8 +268,8 @@ const Eventable = Base =>
245268 }
246269
247270 _wrapOnceHandler ( evtType , handler , context ) {
248- const me = this ;
249- const key = 'Z__' + evtType ;
271+ // const me = this;
272+ const key = generateWrapKey ( evtType ) ;
250273 let called = false ;
251274 const fn = function onceHandler ( ) {
252275 if ( called ) {
@@ -259,7 +282,8 @@ const Eventable = Base =>
259282 } else {
260283 handler . apply ( this , arguments ) ;
261284 }
262- me . off ( evtType , onceHandler , this ) ;
285+ onceHandler . _called = true ;
286+ // me.off(evtType, onceHandler, this);
263287 } ;
264288 fn [ key ] = handler ;
265289 return fn ;
@@ -310,7 +334,8 @@ const Eventable = Base =>
310334 if ( ! this . _eventMap ) {
311335 return this ;
312336 }
313- const handlerChain = this . _eventMap [ eventType . toLowerCase ( ) ] ;
337+ eventType = eventType . toLowerCase ( ) ;
338+ const handlerChain = this . _eventMap [ eventType ] ;
314339 if ( ! handlerChain ) {
315340 return this ;
316341 }
@@ -326,6 +351,10 @@ const Eventable = Base =>
326351 if ( ! queue [ i ] ) {
327352 continue ;
328353 }
354+ const handler = queue [ i ] . handler ;
355+ if ( handler . _called ) {
356+ continue ;
357+ }
329358 context = queue [ i ] . context ;
330359 bubble = true ;
331360 passed = extend ( { } , param ) ;
@@ -341,6 +370,17 @@ const Eventable = Base =>
341370 }
342371 }
343372 }
373+ const eventQueue = this . _eventMap [ eventType ] ;
374+ if ( eventQueue ) {
375+ const queueExcludeOnce = [ ] ;
376+ for ( let i = 0 , len = eventQueue . length ; i < len ; i ++ ) {
377+ const handler = eventQueue [ i ] . handler ;
378+ if ( ! handler . _called ) {
379+ queueExcludeOnce . push ( eventQueue [ i ] ) ;
380+ }
381+ }
382+ this . _eventMap [ eventType ] = queueExcludeOnce ;
383+ }
344384 return this ;
345385 }
346386 } ;
0 commit comments