eventhandler.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. * kity event 实现
  3. */
  4. define(function(require, exports, module) {
  5. // polyfill
  6. (function() {
  7. function CustomEvent(event, params) {
  8. params = params || {
  9. bubbles: false,
  10. cancelable: false,
  11. detail: undefined
  12. };
  13. var evt = document.createEvent('CustomEvent');
  14. evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
  15. return evt;
  16. }
  17. CustomEvent.prototype = window.Event.prototype;
  18. window.CustomEvent = CustomEvent;
  19. })();
  20. var Utils = require('../core/utils'),
  21. ShapeEvent = require('./shapeevent');
  22. // 内部处理器缓存
  23. var INNER_HANDLER_CACHE = {},
  24. // 用户处理器缓存
  25. USER_HANDLER_CACHE = {},
  26. guid = 0;
  27. // 添加事件统一入口
  28. function _addEvent(type, handler, isOnce) {
  29. isOnce = !!isOnce;
  30. if (Utils.isString(type)) {
  31. type = type.match(/\S+/g);
  32. }
  33. Utils.each(type, function(currentType) {
  34. listen.call(this, this.node, currentType, handler, isOnce);
  35. }, this);
  36. return this;
  37. }
  38. // 移除事件统一入口
  39. function _removeEvent(type, handler) {
  40. var userHandlerList = null,
  41. eventId = this._EVNET_UID,
  42. isRemoveAll = handler === undefined;
  43. userHandlerList = USER_HANDLER_CACHE[eventId][type];
  44. //移除指定的监听器
  45. if (!isRemoveAll) {
  46. isRemoveAll = true;
  47. Utils.each(userHandlerList, function removeKityEvent(fn, index) {
  48. if (fn === handler) {
  49. // 不能结束, 需要查找完整个list, 避免丢失移除多次绑定同一个处理器的情况
  50. delete userHandlerList[index];
  51. } else {
  52. isRemoveAll = false;
  53. }
  54. });
  55. }
  56. //删除所有监听器
  57. if (isRemoveAll) {
  58. deleteDomEvent(this.node, type, INNER_HANDLER_CACHE[eventId][type]);
  59. delete USER_HANDLER_CACHE[eventId][type];
  60. delete INNER_HANDLER_CACHE[eventId][type];
  61. }
  62. return this;
  63. }
  64. // 执行绑定, 该方法context为shape或者mixin了eventhandler的对象
  65. function listen(node, type, handler, isOnce) {
  66. var eid = this._EVNET_UID,
  67. targetObject = this;
  68. // 初始化内部监听器
  69. if (!INNER_HANDLER_CACHE[eid]) {
  70. INNER_HANDLER_CACHE[eid] = {};
  71. }
  72. if (!INNER_HANDLER_CACHE[eid][type]) {
  73. // 内部监听器
  74. INNER_HANDLER_CACHE[eid][type] = function kityEventHandler(e) {
  75. e = new ShapeEvent(e || window.event);
  76. Utils.each(USER_HANDLER_CACHE[eid][type], function executeKityEvent(fn) {
  77. var result;
  78. if (fn) {
  79. result = fn.call(targetObject, e);
  80. //once 绑定, 执行完后删除
  81. if (isOnce) {
  82. targetObject.off(type, fn);
  83. }
  84. }
  85. // 如果用户handler里return了false, 则该节点上的此后的同类型事件将不再执行
  86. return result;
  87. }, targetObject);
  88. };
  89. }
  90. // 初始化用户监听器列表
  91. if (!USER_HANDLER_CACHE[eid]) {
  92. USER_HANDLER_CACHE[eid] = {};
  93. }
  94. if (!USER_HANDLER_CACHE[eid][type]) {
  95. USER_HANDLER_CACHE[eid][type] = [handler];
  96. // 绑定对应类型的事件
  97. // dom对象利用dom event进行处理, 非dom对象, 由消息分发机制处理
  98. if (!!node && ('on' + type) in node) {
  99. bindDomEvent(node, type, INNER_HANDLER_CACHE[eid][type]);
  100. }
  101. } else {
  102. USER_HANDLER_CACHE[eid][type].push(handler);
  103. }
  104. }
  105. // 绑定dom事件
  106. function bindDomEvent(node, type, handler) {
  107. if (node.addEventListener) {
  108. node.addEventListener(type, handler, false);
  109. } else {
  110. node.attachEvent('on' + type, handler);
  111. }
  112. }
  113. // 删除dom事件
  114. function deleteDomEvent(node, type, handler) {
  115. if (node.removeEventListener) {
  116. node.removeEventListener(type, handler, false);
  117. } else {
  118. node.detachEvent(type, handler);
  119. }
  120. }
  121. // 触发dom事件
  122. function triggerDomEvent(node, type, params) {
  123. var event = new CustomEvent(type, {
  124. bubbles: true,
  125. cancelable: true
  126. });
  127. event._kityParam = params;
  128. node.dispatchEvent(event);
  129. }
  130. // 发送消息
  131. function sendMessage(messageObj, type, msg) {
  132. var event = null,
  133. handler = null;
  134. var handlers = INNER_HANDLER_CACHE[messageObj._EVNET_UID];
  135. if (!handlers) return;
  136. handler = handlers[type];
  137. if (!handler) {
  138. return;
  139. }
  140. event = Utils.extend({
  141. type: type,
  142. target: messageObj
  143. }, msg || {});
  144. handler.call(messageObj, event);
  145. }
  146. // 对外接口
  147. return require('../core/class').createClass('EventHandler', {
  148. constructor: function() {
  149. this._EVNET_UID = ++guid;
  150. },
  151. addEventListener: function(type, handler) {
  152. return _addEvent.call(this, type, handler, false);
  153. },
  154. addOnceEventListener: function(type, handler) {
  155. return _addEvent.call(this, type, handler, true);
  156. },
  157. removeEventListener: function(type, handler) {
  158. return _removeEvent.call(this, type, handler);
  159. },
  160. on: function(type, handler) {
  161. return this.addEventListener.apply(this, arguments);
  162. },
  163. once: function(type, handler) {
  164. return this.addOnceEventListener.apply(this, arguments);
  165. },
  166. off: function() {
  167. return this.removeEventListener.apply(this, arguments);
  168. },
  169. fire: function(type, params) {
  170. return this.trigger.apply(this, arguments);
  171. },
  172. trigger: function(type, params) {
  173. sendMessage(this, type, params);
  174. return this;
  175. }
  176. });
  177. });