|
3 | 3 | 'use strict';
|
4 | 4 |
|
5 | 5 | var TRIM_REGEXP = /^\s+|\s+$/g,
|
| 6 | + DATA_ATTRIBUTE_HANDLER_ID = 'cssanimid', |
| 7 | + DATA_ATTRIBUTE_HANDLER_ID_PREFIXED = 'data-' + DATA_ATTRIBUTE_HANDLER_ID, |
6 | 8 | CLASS_NAME_ANIM_ACTIVE = ' cssanimactive',
|
7 | 9 | IS_OPERA_EVENT_TYPE_REGEXP = /^o[AT]/,
|
8 | 10 | HANDLER_LIST_INDEX_ANIMATION = 0,
|
|
12 | 14 | animationEventTypeIteration,
|
13 | 15 | animationEventTypeEnd,
|
14 | 16 | transitionEventTypeEnd,
|
15 |
| - handlerList = [undefined,undefined]; |
| 17 | + nextHandlerID = 0, |
| 18 | + handlerCollection = [undefined,undefined]; |
16 | 19 |
|
17 | 20 | function detect() {
|
18 | 21 |
|
19 | 22 | // if already detected support then exit
|
20 | 23 | if (isDetected) return;
|
21 | 24 | isDetected = true;
|
22 | 25 |
|
23 |
| - // list of animation/transition style properties per browser engine and matching DOM event names |
| 26 | + // list of animation/transition properties per browser engine and matching DOM event names |
24 | 27 | // the non-prefixed properties are intentionally checked first
|
25 | 28 | var ANIMATION_DETECT_LIST = [
|
26 | 29 | ['animation','animationstart','animationiteration','animationend'],
|
|
65 | 68 |
|
66 | 69 | obj.addEventListener(type,handler,false);
|
67 | 70 | if (IS_OPERA_EVENT_TYPE_REGEXP.test(type)) {
|
68 |
| - // some earlier versions of Opera (Presto) need lowercased event names |
| 71 | + // some earlier versions of Opera (Presto) raise lowercased event names |
69 | 72 | obj.addEventListener(type.toLowerCase(),handler,false);
|
70 | 73 | }
|
71 | 74 |
|
|
76 | 79 |
|
77 | 80 | obj.removeEventListener(type,handler,false);
|
78 | 81 | if (IS_OPERA_EVENT_TYPE_REGEXP.test(type)) {
|
79 |
| - // some earlier versions of Opera (Presto) need lowercased event names |
| 82 | + // some earlier versions of Opera (Presto) raise lowercased event names |
80 | 83 | obj.removeEventListener(type.toLowerCase(),handler,false);
|
81 | 84 | }
|
82 | 85 |
|
83 | 86 | return true;
|
84 | 87 | }
|
85 | 88 |
|
86 |
| - function getElHandlerListIndex(handlerIndex,el) { |
| 89 | + function getElHandlerCollectionID(handlerIndex,el) { |
87 | 90 |
|
88 |
| - var seekList = handlerList[handlerIndex]; |
89 |
| - if (seekList !== undefined) { |
90 |
| - for (var index = seekList.length - 1;index >= 0;index--) { |
91 |
| - if (seekList[index][0] == el) { |
92 |
| - // found element, return numeric index |
93 |
| - return index; |
94 |
| - } |
95 |
| - } |
96 |
| - } |
| 91 | + var handlerID = (el.hasAttribute(DATA_ATTRIBUTE_HANDLER_ID_PREFIXED)) |
| 92 | + ? el.getAttribute(DATA_ATTRIBUTE_HANDLER_ID_PREFIXED) |
| 93 | + : null; |
97 | 94 |
|
98 |
| - // element not found in handler list |
99 |
| - return false; |
| 95 | + return ( |
| 96 | + (handlerID !== null) && |
| 97 | + (handlerCollection[handlerIndex][handlerID] !== undefined) |
| 98 | + ) |
| 99 | + // found element in collection, return handlerID |
| 100 | + ? handlerID |
| 101 | + // not found |
| 102 | + : false; |
100 | 103 | }
|
101 | 104 |
|
102 |
| - function removeElHandlerItem(handlerIndex,el,index) { |
| 105 | + function removeElHandlerItem(handlerIndex,el,handlerID) { |
103 | 106 |
|
104 |
| - // if index to remove has been given, don't call getElHandlerListIndex() |
105 |
| - if (index === undefined) index = getElHandlerListIndex(handlerIndex,el); |
| 107 | + // if handlerID to remove has been given, don't call getElHandlerCollectionID() |
| 108 | + if (handlerID === undefined) handlerID = getElHandlerCollectionID(handlerIndex,el); |
106 | 109 |
|
107 |
| - if (index !== false) { |
108 |
| - // found element in list, remove from handler list array |
109 |
| - handlerList[handlerIndex].splice(index,1); |
| 110 | + if (handlerID !== false) { |
| 111 | + // found element in collection, now remove |
| 112 | + delete handlerCollection[handlerIndex][handlerID]; |
110 | 113 |
|
111 |
| - // drop the 'animation active' class from element |
| 114 | + // drop data-* attribute and 'animation active' class from element |
| 115 | + el.removeAttribute(DATA_ATTRIBUTE_HANDLER_ID_PREFIXED); |
112 | 116 | el.className =
|
113 | 117 | (' ' + el.className + ' ').
|
114 | 118 | replace(CLASS_NAME_ANIM_ACTIVE + ' ',' ').
|
|
123 | 127 | setTimeout(function() { handler(el,data); });
|
124 | 128 |
|
125 | 129 | } else {
|
126 |
| - if (!handlerList[handlerIndex]) { |
| 130 | + if (!handlerCollection[handlerIndex]) { |
127 | 131 | // setup end handler
|
128 |
| - handlerList[handlerIndex] = []; |
| 132 | + handlerCollection[handlerIndex] = {}; |
129 | 133 | addEvent(docEl,eventTypeEnd,function(event) {
|
130 | 134 |
|
131 | 135 | // ensure event returned the target element
|
132 | 136 | if (event.target) {
|
133 |
| - // get the element handler list index - skip over event if not found |
| 137 | + // get the element handler list ID - skip over if not found |
134 | 138 | var targetEl = event.target,
|
135 |
| - index = getElHandlerListIndex(handlerIndex,targetEl); |
| 139 | + handlerID = getElHandlerCollectionID(handlerIndex,targetEl); |
136 | 140 |
|
137 |
| - if (index !== false) { |
| 141 | + if (handlerID !== false) { |
138 | 142 | // execute handler then remove from handler list
|
139 |
| - var handlerItem = handlerList[handlerIndex][index]; |
140 |
| - removeElHandlerItem(handlerIndex,targetEl,index); |
141 |
| - handlerItem[1](targetEl,handlerItem[2]); |
| 143 | + var handlerItem = handlerCollection[handlerIndex][handlerID]; |
| 144 | + removeElHandlerItem(handlerIndex,targetEl,handlerID); |
| 145 | + handlerItem[0](targetEl,handlerItem[1]); |
142 | 146 | }
|
143 | 147 | }
|
144 | 148 | });
|
|
148 | 152 | removeElHandlerItem(handlerIndex,el);
|
149 | 153 |
|
150 | 154 | // add element to handler list and a 'animation active' class identifier to the target element
|
151 |
| - handlerList[handlerIndex].push([el,handler,data]); |
| 155 | + nextHandlerID++; |
| 156 | + el.setAttribute(DATA_ATTRIBUTE_HANDLER_ID_PREFIXED,nextHandlerID); |
| 157 | + handlerCollection[handlerIndex][nextHandlerID] = [handler,data]; |
152 | 158 | el.className = el.className.replace(TRIM_REGEXP,'') + CLASS_NAME_ANIM_ACTIVE;
|
153 | 159 | }
|
154 | 160 | }
|
|
0 commit comments