1 /** 2 * @fileOverview KISSY.Popup 3 * @author qiaohua@taobao.com, yiminghe@gmail.com 4 */ 5 KISSY.add('overlay/popup', function (S, Overlay, undefined) { 6 7 /** 8 * @class 9 * KISSY Popup Component. 10 * xclass: 'popup'. 11 * @memberOf Overlay 12 * @extends Overlay 13 * @name Popup 14 */ 15 var Popup = Overlay.extend( 16 /** 17 * @lends Overlay.Popup# 18 */ 19 { 20 /** 21 * see {@link Component.UIBase.Box#show} 22 * @name Overlay.Popup#show 23 * @function 24 */ 25 26 27 28 initializer:function () { 29 var self = this, 30 // 获取相关联的 DOM 节点 31 trigger = self.get("trigger"); 32 if (trigger) { 33 if (self.get("triggerType") === 'mouse') { 34 self._bindTriggerMouse(); 35 self.on('afterRenderUI', function () { 36 self._bindContainerMouse(); 37 }); 38 } else { 39 self._bindTriggerClick(); 40 } 41 } 42 }, 43 44 _bindTriggerMouse:function () { 45 var self = this, 46 trigger = self.get("trigger"), 47 timer; 48 49 self.__mouseEnterPopup = function (ev) { 50 self._clearHiddenTimer(); 51 timer = S.later(function () { 52 self._showing(ev); 53 timer = undefined; 54 }, self.get('mouseDelay') * 1000); 55 }; 56 57 S.each(trigger, function (el) { 58 S.one(el).on('mouseenter', self.__mouseEnterPopup); 59 }); 60 61 self._mouseLeavePopup = function () { 62 if (timer) { 63 timer.cancel(); 64 timer = undefined; 65 } 66 67 self._setHiddenTimer(); 68 }; 69 70 S.each(trigger, function (el) { 71 S.one(el).on('mouseleave', self._mouseLeavePopup); 72 }); 73 }, 74 75 _bindContainerMouse:function () { 76 var self = this; 77 self.get('el') 78 .on('mouseleave', self._setHiddenTimer, self) 79 .on('mouseenter', self._clearHiddenTimer, self); 80 }, 81 82 _setHiddenTimer:function () { 83 var self = this; 84 self._hiddenTimer = S.later(function () { 85 self._hiding(); 86 }, self.get('mouseDelay') * 1000); 87 }, 88 89 _clearHiddenTimer:function () { 90 var self = this; 91 if (self._hiddenTimer) { 92 self._hiddenTimer.cancel(); 93 self._hiddenTimer = undefined; 94 } 95 }, 96 97 _bindTriggerClick:function () { 98 var self = this; 99 self.__clickPopup = function (ev) { 100 ev.halt(); 101 if (self.get('toggle')) { 102 self[self.get('visible') ? '_hiding' : '_showing'](ev); 103 } else { 104 self._showing(ev); 105 } 106 }; 107 S.each(self.get("trigger"), function (el) { 108 S.one(el).on('click', self.__clickPopup); 109 }); 110 }, 111 112 _showing:function (ev) { 113 var self = this; 114 self.set('currentTrigger', S.one(ev.target)); 115 self.show(); 116 }, 117 118 _hiding:function () { 119 this.set('currentTrigger', undefined); 120 this.hide(); 121 }, 122 123 destructor:function () { 124 var self = this, 125 root, 126 t = self.get("trigger"); 127 if (t) { 128 if (self.__clickPopup) { 129 t.each(function (el) { 130 el.detach('click', self.__clickPopup); 131 }); 132 } 133 if (self.__mouseEnterPopup) { 134 t.each(function (el) { 135 el.detach('mouseenter', self.__mouseEnterPopup); 136 }); 137 } 138 139 if (self._mouseLeavePopup) { 140 t.each(function (el) { 141 el.detach('mouseleave', self._mouseLeavePopup); 142 }); 143 } 144 } 145 if (root = self.get('el')) { 146 root.detach('mouseleave', self._setHiddenTimer, self) 147 .detach('mouseenter', self._clearHiddenTimer, self); 148 } 149 } 150 }, { 151 ATTRS:/** 152 * @lends Overlay.Popup# 153 */ 154 { 155 /** 156 * Trigger elements to show popup. 157 * @type NodeList 158 */ 159 trigger:{ // 触发器 160 setter:function (v) { 161 if (S.isString(v)) { 162 v = S.all(v); 163 } 164 return v; 165 } 166 }, 167 /** 168 * How to activate trigger element. 169 * "click" or "mouse",Default:"click". 170 * @type String 171 */ 172 triggerType:{ 173 // 触发类型 174 value:'click' 175 }, 176 currentTrigger:{}, 177 /** 178 * When trigger type is mouse, the delayed time to show popup. 179 * Default:0.1, in seconds. 180 * @type Number 181 */ 182 mouseDelay:{ 183 // triggerType 为 mouse 时, Popup 显示的延迟时间, 默认为 100ms 184 value:0.1 185 }, 186 /** 187 * When trigger type is click, whether support toggle. Default:false 188 * @type Boolean 189 */ 190 toggle:{ 191 // triggerType 为 click 时, Popup 是否有toggle功能 192 value:false 193 } 194 } 195 }, { 196 xclass:'popup', 197 priority:20 198 }); 199 200 return Popup; 201 }, { 202 requires:["./base"] 203 }); 204 205 /** 206 * 2011-05-17 207 * - 承玉:利用 initializer , destructor ,ATTRS 208 **/