1 /** 2 * @fileOverview responsible for un-registering event 3 * @author yiminghe@gmail.com 4 */ 5 KISSY.add("event/remove", function (S, Event, DOM, Utils, _data, EVENT_SPECIAL) { 6 var isValidTarget = Utils.isValidTarget, 7 simpleRemove = Utils.simpleRemove; 8 9 S.mix(Event, 10 /** 11 * @lends Event 12 */ 13 { 14 // single target, single type, fixed native 15 __remove:function (isNativeTarget, target, type, fn, scope) { 16 17 if (!target || (isNativeTarget && !isValidTarget(target))) { 18 return; 19 } 20 21 var typedGroups = Utils.getTypedGroups(type); 22 type = typedGroups[0]; 23 var groups = typedGroups[1], 24 selector, 25 // in case type is undefined 26 originalFn = fn, 27 originalScope = scope, 28 hasSelector, s = EVENT_SPECIAL[type]; 29 30 if (S.isObject(fn)) { 31 scope = fn.scope; 32 hasSelector = ("selector" in fn); 33 selector = fn.selector; 34 fn = fn.fn; 35 if (selector) { 36 if (s && s['delegateFix']) { 37 type = s['delegateFix']; 38 } 39 } 40 } 41 42 if (!selector) { 43 if (s && s['onFix']) { 44 type = s['onFix']; 45 } 46 } 47 48 var eventDesc = _data._data(target), 49 events = eventDesc && eventDesc.events, 50 handlers, 51 handler, 52 len, 53 i, 54 j, 55 t, 56 special = (isNativeTarget && EVENT_SPECIAL[type]) || { }; 57 58 if (!events) { 59 return; 60 } 61 62 // remove all types of event 63 if (!type) { 64 for (type in events) { 65 if (events.hasOwnProperty(type)) { 66 Event.__remove(isNativeTarget, 67 target, type + groups, originalFn, 68 originalScope); 69 } 70 } 71 return; 72 } 73 74 var groupsRe; 75 76 if (groups) { 77 groupsRe = Utils.getGroupsRe(groups); 78 } 79 80 if ((handlers = events[type])) { 81 len = handlers.length; 82 // 移除 fn 83 if ((fn || hasSelector || groupsRe ) && len) { 84 scope = scope || target; 85 86 for (i = 0, j = 0, t = []; i < len; ++i) { 87 handler = handlers[i]; 88 var handlerScope = handler.scope || target; 89 if ( 90 (scope != handlerScope) || 91 // 指定了函数,函数不相等,保留 92 (fn && fn != handler.fn) || 93 // 1.没指定函数 94 // 1.1 没有指定选择器,删掉 else2 95 // 1.2 指定选择器,字符串为空 96 // 1.2.1 指定选择器,字符串为空,待比较 handler 有选择器,删掉 else 97 // 1.2.2 指定选择器,字符串为空,待比较 handler 没有选择器,保留 98 // 1.3 指定选择器,字符串不为空,字符串相等,删掉 else 99 // 1.4 指定选择器,字符串不为空,字符串不相等,保留 100 // 2.指定了函数且函数相等 101 // 2.1 没有指定选择器,删掉 else 102 // 2.2 指定选择器,字符串为空 103 // 2.2.1 指定选择器,字符串为空,待比较 handler 有选择器,删掉 else 104 // 2.2.2 指定选择器,字符串为空,待比较 handler 没有选择器,保留 105 // 2.3 指定选择器,字符串不为空,字符串相等,删掉 else 106 // 2.4 指定选择器,字符串不为空,字符串不相等,保留 107 ( 108 hasSelector && 109 ( 110 (selector && selector != handler.selector) || 111 (!selector && !handler.selector) 112 ) 113 ) || 114 115 // 指定了删除的某些组,而该 handler 不属于这些组,保留,否则删除 116 (groupsRe && !handler.groups.match(groupsRe)) 117 118 ) { 119 t[j++] = handler; 120 } 121 else { 122 if (handler.selector && handlers.delegateCount) { 123 handlers.delegateCount--; 124 } 125 if (handler.last && handlers.lastCount) { 126 handlers.lastCount--; 127 } 128 if (special.remove) { 129 special.remove.call(target, handler); 130 } 131 } 132 } 133 t.delegateCount = handlers.delegateCount; 134 t.lastCount = handlers.lastCount; 135 events[type] = t; 136 len = t.length; 137 } else { 138 // 全部删除 139 len = 0; 140 } 141 142 if (!len) { 143 // remove(el, type) or fn 已移除光 144 // dom node need to detach handler from dom node 145 if (isNativeTarget && 146 (!special['tearDown'] || 147 special['tearDown'].call(target) === false)) { 148 simpleRemove(target, type, eventDesc.handler); 149 } 150 // remove target's single event description 151 delete events[type]; 152 } 153 } 154 155 // remove target's all events description 156 if (S.isEmptyObject(events)) { 157 eventDesc.handler.target = null; 158 delete eventDesc.handler; 159 delete eventDesc.events; 160 Event._removeData(target); 161 } 162 }, 163 164 /** 165 * Detach an event or set of events from an element. similar to removeEventListener in DOM3 Events 166 * @param targets KISSY selector 167 * @param {String} [type] The type of event to remove. 168 * use space to separate multiple event types. 169 * @param {Function} [fn] The event handler/listener. 170 * @param {Object} [scope] The scope (this reference) in which the handler function is executed. 171 */ 172 remove:function (targets, type, fn, scope) { 173 174 type = S.trim(type); 175 176 if (Utils.batchForType(Event.remove, targets, type, fn, scope)) { 177 return targets; 178 } 179 180 targets = DOM.query(targets); 181 182 for (var i = targets.length - 1; i >= 0; i--) { 183 Event.__remove(true, targets[i], type, fn, scope); 184 } 185 186 return targets; 187 188 } 189 }); 190 }, { 191 requires:['./base', 'dom', './utils', './data', './special'] 192 });