PageRenderTime 56ms CodeModel.GetById 2ms app.highlight 49ms RepoModel.GetById 1ms app.codeStats 1ms

/KitJs/src/js/event.js

https://github.com/wuxq/KitJs
JavaScript | 496 lines | 320 code | 4 blank | 172 comment | 96 complexity | d37b8f83328ce06409bd52198f78a782 MD5 | raw file
  1/**
  2 * 事件扩展,加载该js之后,$kit.ev事件既可以支持全浏览器拖拽
  3 * @class $Kit.Event
  4 * @requires kit.js
  5 * @requires dom.js
  6 * @see <a href="https://github.com/xueduany/KitJs/blob/master/KitJs/src/js/event.js">Source code</a>
  7 */
  8$Kit.Event = function() {
  9	//
 10	/**
 11	 * 原始的ev事件
 12	 * @member _ev
 13	 * @instance
 14	 * @memberOf $Kit.Event
 15	 */
 16	this._ev = function() {
 17		$Kit.prototype.ev.apply($kit, arguments);
 18	}
 19	/**
 20	 * 当前拖拽事件的拖拽元素
 21	 * @member dragElement
 22	 * @instance
 23	 * @memberOf $Kit.Event
 24	 */
 25	this.dragElement = undefined;
 26	/*$kit.ev = function() {
 27	 $kit.event.ev.apply($kit.event, arguments);
 28	 }*/
 29	this.eventExtraInfoFnArray = [];
 30	this.registExtraEventInfo(function() {
 31		return $Kit.prototype.evExtra.apply($kit, arguments);
 32	});
 33	this.registExtraEventInfo(function() {
 34		return {
 35			dragElement : this.dragElement
 36		};
 37	});
 38	this.registExtraEventInfo(function() {
 39		return {
 40			dragStartEventInfo : this.dragStartEventInfo
 41		};
 42	});
 43}
 44$kit.merge($Kit.Event.prototype,
 45/**
 46 * @lends $Kit.Event.prototype
 47 * @enum
 48 */
 49{
 50	KEYCODE_UP : 38,
 51	KEYCODE_DOWN : 40,
 52	KEYCODE_LEFT : 37,
 53	KEYCODE_RIGHT : 39,
 54	//
 55	KEYCODE_ADD : 107,
 56	KEYCODE_SUB : 109,
 57	KEYCODE_MULTIPLY : 106,
 58	KEYCODE_DIVIDE : 111,
 59	//
 60	KEYCODE_ENTER : 13,
 61	KEYCODE_ESC : 27,
 62	KEYCODE_BACKSPACE : 8,
 63	KEYCODE_TAB : 9,
 64	//
 65	KEYCODE_SHIFT : 16,
 66	KEYCODE_CTRL : 17,
 67	KEYCODE_ALT : 18,
 68	//
 69	KEYCODE_INSERT : 45,
 70	KEYCODE_DELETE : 46,
 71	//
 72	KEYCODE_PAGEUP : 33,
 73	KEYCODE_PAGEDOWN : 34
 74},
 75/**
 76 * @lends $Kit.Event.prototype
 77 */
 78{
 79	//event增强start
 80	/**
 81	 * 递归
 82	 * @private
 83	 */
 84	recurEv : function(evCfg, fn) {
 85		var me = this;
 86		if($kit.isAry(evCfg.el)) {
 87			$kit.each(evCfg.el, function(el) {
 88				fn.call(me, $kit.join(evCfg, {
 89					el : el
 90				}));
 91			});
 92		} else if($kit.isCanSplit2Ary(evCfg.el)) {
 93			me.recurEv($kit.join(evCfg, {
 94				el : evCfg.el.split($kit.CONSTANTS.REGEXP_SPACE)
 95			}), fn);
 96		} else if($kit.isStr(evCfg.el)) {
 97			var _el = $kit.el(evCfg.el);
 98			if($kit.isEmpty(_el)) {
 99				_el = $kit.el("#" + evCfg.el);
100			}
101			if(!$kit.isEmpty(_el)) {
102				fn.call(me, $kit.join(evCfg, {
103					el : _el
104				}));
105			}
106		} else if($kit.isAry(evCfg.ev)) {
107			$kit.each(evCfg.ev, function(ev) {
108				fn.call(me, $kit.join(evCfg, {
109					ev : ev
110				}));
111			});
112		} else if($kit.isCanSplit2Ary(evCfg.ev)) {
113			me.recurEv($kit.join(evCfg, {
114				ev : evCfg.ev.split($kit.CONSTANTS.REGEXP_SPACE)
115			}), fn);
116		} else {
117			return true;
118		}
119	},
120	/**
121	 * kit事件注册方法,支持拖拽
122	 * @param {Object} config
123	 * @param {Selector|Element|NodeList} config.el 触发事件的元素,等于event.currentTarget
124	 * @param {String} config.ev 事件type,如click
125	 * @param {Function} config.fn 事件方法
126	 * @param {Object} config.scope this指针
127	 */
128	ev : function(config) {
129		var me = this, defaultConfig = {
130			el : null,
131			ev : null,
132			fn : null
133		}
134		config = $kit.join(defaultConfig, config);
135		if($kit.isEmpty(config.el) || $kit.isEmpty(config.ev) || !$kit.isFn(config.fn)) {
136			return;
137		}
138		if(me.recurEv(config, me.ev)) {
139			var ev = config.ev.trim(), el = config.el;
140			if('ondrag' in el) {
141				//使用IE自带的drag事件,考虑到HTML5的普及,直接使用现成的
142				if(me._isDragEv(ev) && el._flag_kitjs_drag_regist != true) {
143					el._flag_kitjs_drag_regist = true;
144					el.style.cursor = 'move';
145					$kit.attr(el, 'draggable', 'true');
146					if($kit.isIE()) {
147						//如果是IE
148						me._ev({
149							el : el,
150							ev : 'mousedown',
151							fn : function(e) {
152								var el = e.currentTarget;
153								el.dragDrop && el.dragDrop();
154								el._kitjs_dd_mousedown = true;
155								//el._kitjs_dd_origin_positoin = $kit.css(el, 'position');
156							}
157						});
158						me._ev({
159							el : el,
160							ev : 'dragstart',
161							fn : function(e) {
162								var el = e.currentTarget;
163								//e.dataTransfer.effectAllowed = "all";
164								me.dragElement = e.currentTarget;
165								me.dragStartEventInfo = {
166									clientX : e.clientX,
167									clientY : e.clientY,
168									offsetTarget : e.target.offsetParent,
169									offsetTargetOffset : $kit.offset(e.target.offsetParent),
170									offsetTargetClientOffset : $kit.dom.clientOffset(e.target.offsetParent)
171								}
172								e.dataTransfer.setData("text", e.currentTarget.innerHTML);
173								//e.dataTransfer.setDragImage(e.target, 0, 0);
174								if(el._kitjs_dd_start != true) {
175									//
176									// var cloneNode = document.createElement('div');
177									// $kit.css(cloneNode, {
178									// position : 'absolute',
179									// display : 'block',
180									// width : $kit.offset(el).width,
181									// height : $kit.offset(el).height,
182									// border : '2px dashed #aaa',
183									// backgroundColor : 'transparent',
184									// opacity : 0.5
185									// });
186									// document.body.appendChild(cloneNode);
187									// $kit.css(cloneNode, {
188									// top : e.pageY - 2,
189									// left : e.pageX - 2
190									// });
191									// $kit.css(el, {
192									// position : 'absolute',
193									// top : el.offsetTop,
194									// left : el.offsetLeft
195									// });
196
197									el._kitjs_dd_start = true;
198									el._kitjs_dd_drag = true;
199									//el._kitjs_dd_cloneNode = cloneNode;
200								}
201							}
202						});
203						me._ev({
204							el : el,
205							ev : 'drag',
206							fn : function(e) {
207								var el = e.currentTarget;
208								//e.dataTransfer.effectAllowed = "all";
209								if(el._kitjs_dd_mousedown == true) {
210									// $kit.css(el._kitjs_dd_cloneNode, {
211									// position : 'absolute',
212									// display : 'block',
213									// top : e.pageY - 2,
214									// left : e.pageX - 2
215									// });
216									el._kitjs_dd_drag = true;
217								}
218							}
219						});
220						me._ev({
221							el : el,
222							ev : 'dragend',
223							fn : function(e) {
224								me.dragElement = null;
225								me.dragStartEventInfo = null;
226								var el = e.currentTarget;
227								el._kitjs_dd_mousedown = false;
228								el._kitjs_dd_drag = false;
229								el._kitjs_dd_start = false;
230
231								// $kit.css(el._kitjs_dd_cloneNode, {
232								// display : 'none',
233								// 'z-index' : -1
234								// });
235
236							}
237						});
238						el._kitjs_dd_init = true;
239						el._kitjs_dd_start = false;
240						el._kitjs_dd_drag = false;
241						el._kitjs_dd_mousedown = true;
242					} else {
243						//非IE
244						me._ev({
245							el : el,
246							ev : 'dragstart',
247							fn : function(e) {
248								var el = e.currentTarget;
249								//e.dataTransfer.dropEffect = 'move';
250								//e.dataTransfer.effectAllowed = "all";
251								//e.dataTransfer.setDragImage(ev.target, 0, 0);
252								me.dragElement = e.currentTarget;
253								e.dataTransfer.setData("text", e.currentTarget.innerHTML);
254								me.dragStartEventInfo = {
255									clientX : e.clientX,
256									clientY : e.clientY,
257									screenX : e.screenX,
258									screenY : e.screenY,
259									layerX : e.layerX,
260									layerY : e.layerY,
261									offsetTarget : e.target.offsetParent,
262									offsetTargetOffset : $kit.offset(e.target.offsetParent),
263									offsetTargetClientOffset : $kit.dom.clientOffset(e.target.offsetParent)
264								}
265							}
266						});
267						me._ev({
268							el : el,
269							ev : 'drag',
270							fn : function(e) {
271								//e.dataTransfer.effectAllowed = "all";
272							}
273						});
274						me._ev({
275							el : el,
276							ev : 'dragend',
277							fn : function(e) {
278								me.dragElement = null;
279							}
280						});
281					}
282				} else if(me._isDropEv(ev) && el._flag_kitjs_drop_regist != true) {
283					el._flag_kitjs_drop_regist = true;
284					me._ev({
285						el : el,
286						ev : 'dragover',
287						fn : function(e) {
288							e.stopDefault();
289						}
290					});
291				} else {
292					//mousemove代替drag事件,暂时hold
293					/*
294					 if(!el._kitjs_dd_init) {
295					 me._ev({
296					 el : el,
297					 ev : 'mousedown',
298					 fn : function(e) {
299					 var el = e.currentTarget;
300					 if(el._kitjs_dd_init) {
301					 el._kitjs_dd_start = false;
302					 el._kitjs_dd_drag = false;
303					 el._kitjs_dd_mousedown = true;
304					 }
305					 }
306					 });
307					 el._kitjs_dd_init = true;
308					 me._ev({
309					 el : el,
310					 ev : 'mousemove',
311					 fn : function(e) {
312					 var el = e.currentTarget;
313					 if(el._kitjs_dd_init == true && el._kitjs_dd_mousedown == true) {
314					 if(el._kitjs_dd_start != true) {
315					 $kit.newEv({
316					 el : el,
317					 ev : 'dragstart'
318					 });
319					 el._kitjs_dd_start = true;
320					 }
321					 el._kitjs_dd_drag = true;
322					 $kit.newEv({
323					 el : el,
324					 ev : 'drag'
325					 });
326					 }
327					 }
328					 });
329					 me._ev({
330					 el : el,
331					 ev : 'mouseup',
332					 fn : function(e) {
333					 var el = e.currentTarget;
334					 if(el._kitjs_dd_drag == true && el._kitjs_dd_init == true) {
335					 $kit.newEv({
336					 el : el,
337					 ev : 'dragend'
338					 });
339					 el._kitjs_dd_drag = false;
340					 el._kitjs_dd_start = false;
341					 el._kitjs_dd_mousedown = false;
342					 }
343					 }
344					 });
345					 }
346					 */
347				}
348				//
349			}
350			me._ev(config);
351		}
352	},
353	_isDragEv : function(ev) {
354		var ev = ev.toLowerCase().trim();
355		if(ev == 'dragstart'//
356		|| ev == 'drag'//
357		|| ev == 'dragend'//
358		) {
359			return true;
360		}
361		return false;
362	},
363	_isDropEv : function(ev) {
364		var ev = ev.toLowerCase().trim();
365		if(ev == 'dragenter'//
366		|| ev == 'dragleave'//
367		|| ev == 'dragover'//
368		|| ev == 'drop'//
369		) {
370			return true;
371		}
372		return false;
373	},
374	//event增强end
375	draggable : function(el) {
376		var me = this;
377		if(el['kitjs-draggable']) {
378			return;
379		}
380		el['kitjs-draggable'] = true;
381		me.ev({
382			el : el,
383			ev : 'drag',
384			fn : function(e, cfg) {
385				//e.dataTransfer.setDragImage(e.target, 0, 0);//设置拖拽图片
386				if(e.dragStartEventInfo && e.dragStartEventInfo.offsetTarget != document.body) {
387					var position = $kit.css(e.dragStartEventInfo.offsetTarget, 'position');
388					var distanceX = 0, distanceY = 0;
389					/*
390					 if(e.clientX == 0 && e.screenX > 0) {
391					 distanceX = e.screenX - e.dragStartEventInfo.screenX;
392					 } else if(e.clientX == 0 && e.screenX == 0 && e.layerX > 0) {
393					 distanceX = e.layerX - e.dragStartEventInfo.layerX;
394					 } else {
395					 distanceX = e.clientX - e.dragStartEventInfo.clientX;
396					 }
397					 if(e.clientY == 0 && e.screenY > 0) {
398					 distanceY = e.screenY - e.dragStartEventInfo.screenY;
399					 } else if(e.clientY == 0 && e.screenY == 0 && e.layerY > 0) {
400					 distanceY = e.layerY - e.dragStartEventInfo.layerY;
401					 } else {
402					 distanceY = e.clientY - e.dragStartEventInfo.clientY;
403					 }*/
404					if(e.clientX == 0 && e.screenX > 0) {
405						distanceX = e.screenX - e.dragStartEventInfo.screenX;
406					} else if(e.clientX > 0) {
407						distanceX = e.clientX - e.dragStartEventInfo.clientX;
408					}
409					if(e.clientY == 0 && e.screenY > 0) {
410						distanceY = e.screenY - e.dragStartEventInfo.screenY;
411					} else if(e.clientY > 0) {
412						distanceY = e.clientY - e.dragStartEventInfo.clientY;
413					}
414					if(distanceY != 0 || distanceX != 0) {
415						if(position && position.toLowerCase() == 'fixed') {
416							var pos = {
417								top : e.dragStartEventInfo.offsetTargetClientOffset.top + distanceY + 'px',
418								left : e.dragStartEventInfo.offsetTargetClientOffset.left + distanceX + 'px'
419							};
420							$kit.css(e.dragStartEventInfo.offsetTarget, pos);
421						} else if(position && position.toLowerCase() == 'absolute') {
422							var pos = {
423								top : e.dragStartEventInfo.offsetTargetOffset.top + distanceY + 'px',
424								left : e.dragStartEventInfo.offsetTargetOffset.left + distanceX + 'px'
425							};
426							$kit.css(e.dragStartEventInfo.offsetTarget, pos);
427						}
428					}
429				}
430			},
431			scope : el
432		});
433		me.ev({
434			el : el,
435			ev : 'dragend',
436			fn : function(e, cfg) {
437				if(e.dragStartEventInfo && e.dragStartEventInfo.offsetTarget != document.body) {
438					var position = $kit.css(e.dragStartEventInfo.offsetTarget, 'position');
439					var distanceX = 0, distanceY = 0;
440					if(e.clientX == 0 && e.screenX > 0) {
441						distanceX = e.screenX - e.dragStartEventInfo.screenX;
442					} else {
443						distanceX = e.clientX - e.dragStartEventInfo.clientX;
444					}
445					if(e.clientY == 0 && e.screenY > 0) {
446						distanceY = e.screenY - e.dragStartEventInfo.screenY;
447					} else {
448						distanceY = e.clientY - e.dragStartEventInfo.clientY;
449					}
450					if(distanceY != 0 || distanceX != 0) {
451						if(position && position.toLowerCase() == 'fixed') {
452							$kit.css(e.dragStartEventInfo.offsetTarget, {
453								top : e.dragStartEventInfo.offsetTargetClientOffset.top + distanceY + 'px',
454								left : e.dragStartEventInfo.offsetTargetClientOffset.left + distanceX + 'px'
455							});
456						} else if(position && position.toLowerCase() == 'absolute') {
457							$kit.css(e.dragStartEventInfo.offsetTarget, {
458								top : e.dragStartEventInfo.offsetTargetOffset.top + distanceY + 'px',
459								left : e.dragStartEventInfo.offsetTargetOffset.left + distanceX + 'px'
460							});
461						}
462					}
463				}
464			},
465			scope : el
466		});
467	},
468	evExtra : function(ev) {
469		var me = this;
470		var re = {};
471		for(var i = 0; i < $kit.event.eventExtraInfoFnArray.length; i++) {
472			if($kit.isFn(me.eventExtraInfoFnArray[i])) {
473				$kit.merge(re, me.eventExtraInfoFnArray[i].call(me, ev));
474			} else {
475				$kit.merge(re, me.eventExtraInfoFnArray[i]);
476			}
477		}
478		return re;
479	},
480	registExtraEventInfo : function(fn) {
481		this.eventExtraInfoFnArray.push(fn);
482	}
483});
484/**
485 * $Kit.Event的实例,直接通过这个实例访问$Kit.Event所有方法
486 * @global
487 * @type $Kit.Event
488 */
489
490$kit.event = new $Kit.Event();
491/*$kit.ev = function() {
492	$kit.event.ev.apply($kit.event, arguments);
493};*/
494$kit.evExtra = function() {
495	return $Kit.Event.prototype.evExtra.apply($kit.event, arguments);
496};