Source: node_modules/@egjs/component/src/component.js

  1. /**
  2. * Copyright (c) 2015 NAVER Corp.
  3. * egjs projects are licensed under the MIT license
  4. */
  5. /**
  6. * A class used to manage events and options in a component
  7. * @ko 컴포넌트의 이벤트와 옵션을 관리할 수 있게 하는 클래스
  8. * @alias eg.Component
  9. */
  10. class Component {
  11. /**
  12. * @support {"ie": "7+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.1+ (except 3.x)"}
  13. */
  14. constructor() {
  15. this._eventHandler = {};
  16. this.options = {};
  17. }
  18. /**
  19. * Triggers a custom event.
  20. * @ko 커스텀 이벤트를 발생시킨다
  21. * @param {String} eventName The name of the custom event to be triggered <ko>발생할 커스텀 이벤트의 이름</ko>
  22. * @param {Object} customEvent Event data to be sent when triggering a custom event <ko>커스텀 이벤트가 발생할 때 전달할 데이터</ko>
  23. * @return {Boolean} Indicates whether the event has occurred. If the stop() method is called by a custom event handler, it will return false and prevent the event from occurring. <a href="https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F">Ref</a> <ko>이벤트 발생 여부. 커스텀 이벤트 핸들러에서 stop() 메서드를 호출하면 'false'를 반환하고 이벤트 발생을 중단한다. <a href="https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F">참고</a></ko>
  24. * @example
  25. class Some extends eg.Component {
  26. some(){
  27. if(this.trigger("beforeHi")){ // When event call to stop return false.
  28. this.trigger("hi");// fire hi event.
  29. }
  30. }
  31. }
  32. const some = new Some();
  33. some.on("beforeHi", (e) => {
  34. if(condition){
  35. e.stop(); // When event call to stop, `hi` event not call.
  36. }
  37. });
  38. some.on("hi", (e) => {
  39. // `currentTarget` is component instance.
  40. console.log(some === e.currentTarget); // true
  41. });
  42. // If you want to more know event design. You can see article.
  43. // https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F
  44. */
  45. trigger(eventName, customEvent = {}, ...restParam) {
  46. let handlerList = this._eventHandler[eventName] || [];
  47. const hasHandlerList = handlerList.length > 0;
  48. if (!hasHandlerList) {
  49. return true;
  50. }
  51. // If detach method call in handler in first time then handeler list calls.
  52. handlerList = handlerList.concat();
  53. customEvent.eventType = eventName;
  54. let isCanceled = false;
  55. let arg = [customEvent];
  56. let i = 0;
  57. customEvent.stop = () => { isCanceled = true; };
  58. customEvent.currentTarget = this;
  59. if (restParam.length >= 1) {
  60. arg = arg.concat(restParam);
  61. }
  62. for (i = 0; handlerList[i]; i++) {
  63. handlerList[i].apply(this, arg);
  64. }
  65. return !isCanceled;
  66. }
  67. /**
  68. * Executed event just one time.
  69. * @ko 이벤트가 한번만 실행된다.
  70. * @param {eventName} eventName The name of the event to be attached <ko>등록할 이벤트의 이름</ko>
  71. * @param {Function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko>
  72. * @return {eg.Component} An instance of a component itself<ko>컴포넌트 자신의 인스턴스</ko>
  73. * @example
  74. class Some extends eg.Component {
  75. hi() {
  76. alert("hi");
  77. }
  78. thing() {
  79. this.once("hi", this.hi);
  80. }
  81. }
  82. var some = new Some();
  83. some.thing();
  84. some.trigger("hi");
  85. // fire alert("hi");
  86. some.trigger("hi");
  87. // Nothing happens
  88. */
  89. once(eventName, handlerToAttach) {
  90. if (typeof eventName === "object" &&
  91. typeof handlerToAttach === "undefined") {
  92. const eventHash = eventName;
  93. let i;
  94. for (i in eventHash) {
  95. this.once(i, eventHash[i]);
  96. }
  97. return this;
  98. } else if (typeof eventName === "string" &&
  99. typeof handlerToAttach === "function") {
  100. const self = this;
  101. this.on(eventName, function listener(...arg) {
  102. handlerToAttach.apply(self, arg);
  103. self.off(eventName, listener);
  104. });
  105. }
  106. return this;
  107. }
  108. /**
  109. * Checks whether an event has been attached to a component.
  110. * @ko 컴포넌트에 이벤트가 등록됐는지 확인한다.
  111. * @param {String} eventName The name of the event to be attached <ko>등록 여부를 확인할 이벤트의 이름</ko>
  112. * @return {Boolean} Indicates whether the event is attached. <ko>이벤트 등록 여부</ko>
  113. * @example
  114. class Some extends eg.Component {
  115. some() {
  116. this.hasOn("hi");// check hi event.
  117. }
  118. }
  119. */
  120. hasOn(eventName) {
  121. return !!this._eventHandler[eventName];
  122. }
  123. /**
  124. * Attaches an event to a component.
  125. * @ko 컴포넌트에 이벤트를 등록한다.
  126. * @param {eventName} eventName The name of the event to be attached <ko>등록할 이벤트의 이름</ko>
  127. * @param {Function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko>
  128. * @return {eg.Component} An instance of a component itself<ko>컴포넌트 자신의 인스턴스</ko>
  129. * @example
  130. class Some extends eg.Component {
  131. hi() {
  132. console.log("hi");
  133. }
  134. some() {
  135. this.on("hi",this.hi); //attach event
  136. }
  137. }
  138. */
  139. on(eventName, handlerToAttach) {
  140. if (typeof eventName === "object" &&
  141. typeof handlerToAttach === "undefined") {
  142. const eventHash = eventName;
  143. let name;
  144. for (name in eventHash) {
  145. this.on(name, eventHash[name]);
  146. }
  147. return this;
  148. } else if (typeof eventName === "string" &&
  149. typeof handlerToAttach === "function") {
  150. let handlerList = this._eventHandler[eventName];
  151. if (typeof handlerList === "undefined") {
  152. this._eventHandler[eventName] = [];
  153. handlerList = this._eventHandler[eventName];
  154. }
  155. handlerList.push(handlerToAttach);
  156. }
  157. return this;
  158. }
  159. /**
  160. * Detaches an event from the component.
  161. * @ko 컴포넌트에 등록된 이벤트를 해제한다
  162. * @param {eventName} eventName The name of the event to be detached <ko>해제할 이벤트의 이름</ko>
  163. * @param {Function} handlerToDetach The handler function of the event to be detached <ko>해제할 이벤트의 핸들러 함수</ko>
  164. * @return {eg.Component} An instance of a component itself <ko>컴포넌트 자신의 인스턴스</ko>
  165. * @example
  166. class Some extends eg.Component {
  167. hi() {
  168. console.log("hi");
  169. }
  170. some() {
  171. this.off("hi",this.hi); //detach event
  172. }
  173. }
  174. */
  175. off(eventName, handlerToDetach) {
  176. // All event detach.
  177. if (typeof eventName === "undefined") {
  178. this._eventHandler = {};
  179. return this;
  180. }
  181. // All handler of specific event detach.
  182. if (typeof handlerToDetach === "undefined") {
  183. if (typeof eventName === "string") {
  184. this._eventHandler[eventName] = undefined;
  185. return this;
  186. } else {
  187. const eventHash = eventName;
  188. let name;
  189. for (name in eventHash) {
  190. this.off(name, eventHash[name]);
  191. }
  192. return this;
  193. }
  194. }
  195. // The handler of specific event detach.
  196. let handlerList = this._eventHandler[eventName];
  197. if (handlerList) {
  198. let k;
  199. let handlerFunction;
  200. for (k = 0; (handlerFunction = handlerList[k]) !== undefined; k++) {
  201. if (handlerFunction === handlerToDetach) {
  202. handlerList = handlerList.splice(k, 1);
  203. break;
  204. }
  205. }
  206. }
  207. return this;
  208. }
  209. }
  210. export default Component;
comments powered by Disqus