/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. el._kitjs_dd_start = true;
  197. el._kitjs_dd_drag = true;
  198. //el._kitjs_dd_cloneNode = cloneNode;
  199. }
  200. }
  201. });
  202. me._ev({
  203. el : el,
  204. ev : 'drag',
  205. fn : function(e) {
  206. var el = e.currentTarget;
  207. //e.dataTransfer.effectAllowed = "all";
  208. if(el._kitjs_dd_mousedown == true) {
  209. // $kit.css(el._kitjs_dd_cloneNode, {
  210. // position : 'absolute',
  211. // display : 'block',
  212. // top : e.pageY - 2,
  213. // left : e.pageX - 2
  214. // });
  215. el._kitjs_dd_drag = true;
  216. }
  217. }
  218. });
  219. me._ev({
  220. el : el,
  221. ev : 'dragend',
  222. fn : function(e) {
  223. me.dragElement = null;
  224. me.dragStartEventInfo = null;
  225. var el = e.currentTarget;
  226. el._kitjs_dd_mousedown = false;
  227. el._kitjs_dd_drag = false;
  228. el._kitjs_dd_start = false;
  229. // $kit.css(el._kitjs_dd_cloneNode, {
  230. // display : 'none',
  231. // 'z-index' : -1
  232. // });
  233. }
  234. });
  235. el._kitjs_dd_init = true;
  236. el._kitjs_dd_start = false;
  237. el._kitjs_dd_drag = false;
  238. el._kitjs_dd_mousedown = true;
  239. } else {
  240. //非IE
  241. me._ev({
  242. el : el,
  243. ev : 'dragstart',
  244. fn : function(e) {
  245. var el = e.currentTarget;
  246. //e.dataTransfer.dropEffect = 'move';
  247. //e.dataTransfer.effectAllowed = "all";
  248. //e.dataTransfer.setDragImage(ev.target, 0, 0);
  249. me.dragElement = e.currentTarget;
  250. e.dataTransfer.setData("text", e.currentTarget.innerHTML);
  251. me.dragStartEventInfo = {
  252. clientX : e.clientX,
  253. clientY : e.clientY,
  254. screenX : e.screenX,
  255. screenY : e.screenY,
  256. layerX : e.layerX,
  257. layerY : e.layerY,
  258. offsetTarget : e.target.offsetParent,
  259. offsetTargetOffset : $kit.offset(e.target.offsetParent),
  260. offsetTargetClientOffset : $kit.dom.clientOffset(e.target.offsetParent)
  261. }
  262. }
  263. });
  264. me._ev({
  265. el : el,
  266. ev : 'drag',
  267. fn : function(e) {
  268. //e.dataTransfer.effectAllowed = "all";
  269. }
  270. });
  271. me._ev({
  272. el : el,
  273. ev : 'dragend',
  274. fn : function(e) {
  275. me.dragElement = null;
  276. }
  277. });
  278. }
  279. } else if(me._isDropEv(ev) && el._flag_kitjs_drop_regist != true) {
  280. el._flag_kitjs_drop_regist = true;
  281. me._ev({
  282. el : el,
  283. ev : 'dragover',
  284. fn : function(e) {
  285. e.stopDefault();
  286. }
  287. });
  288. } else {
  289. //mousemove代替drag事件,暂时hold
  290. /*
  291. if(!el._kitjs_dd_init) {
  292. me._ev({
  293. el : el,
  294. ev : 'mousedown',
  295. fn : function(e) {
  296. var el = e.currentTarget;
  297. if(el._kitjs_dd_init) {
  298. el._kitjs_dd_start = false;
  299. el._kitjs_dd_drag = false;
  300. el._kitjs_dd_mousedown = true;
  301. }
  302. }
  303. });
  304. el._kitjs_dd_init = true;
  305. me._ev({
  306. el : el,
  307. ev : 'mousemove',
  308. fn : function(e) {
  309. var el = e.currentTarget;
  310. if(el._kitjs_dd_init == true && el._kitjs_dd_mousedown == true) {
  311. if(el._kitjs_dd_start != true) {
  312. $kit.newEv({
  313. el : el,
  314. ev : 'dragstart'
  315. });
  316. el._kitjs_dd_start = true;
  317. }
  318. el._kitjs_dd_drag = true;
  319. $kit.newEv({
  320. el : el,
  321. ev : 'drag'
  322. });
  323. }
  324. }
  325. });
  326. me._ev({
  327. el : el,
  328. ev : 'mouseup',
  329. fn : function(e) {
  330. var el = e.currentTarget;
  331. if(el._kitjs_dd_drag == true && el._kitjs_dd_init == true) {
  332. $kit.newEv({
  333. el : el,
  334. ev : 'dragend'
  335. });
  336. el._kitjs_dd_drag = false;
  337. el._kitjs_dd_start = false;
  338. el._kitjs_dd_mousedown = false;
  339. }
  340. }
  341. });
  342. }
  343. */
  344. }
  345. //
  346. }
  347. me._ev(config);
  348. }
  349. },
  350. _isDragEv : function(ev) {
  351. var ev = ev.toLowerCase().trim();
  352. if(ev == 'dragstart'//
  353. || ev == 'drag'//
  354. || ev == 'dragend'//
  355. ) {
  356. return true;
  357. }
  358. return false;
  359. },
  360. _isDropEv : function(ev) {
  361. var ev = ev.toLowerCase().trim();
  362. if(ev == 'dragenter'//
  363. || ev == 'dragleave'//
  364. || ev == 'dragover'//
  365. || ev == 'drop'//
  366. ) {
  367. return true;
  368. }
  369. return false;
  370. },
  371. //event增强end
  372. draggable : function(el) {
  373. var me = this;
  374. if(el['kitjs-draggable']) {
  375. return;
  376. }
  377. el['kitjs-draggable'] = true;
  378. me.ev({
  379. el : el,
  380. ev : 'drag',
  381. fn : function(e, cfg) {
  382. //e.dataTransfer.setDragImage(e.target, 0, 0);//设置拖拽图片
  383. if(e.dragStartEventInfo && e.dragStartEventInfo.offsetTarget != document.body) {
  384. var position = $kit.css(e.dragStartEventInfo.offsetTarget, 'position');
  385. var distanceX = 0, distanceY = 0;
  386. /*
  387. if(e.clientX == 0 && e.screenX > 0) {
  388. distanceX = e.screenX - e.dragStartEventInfo.screenX;
  389. } else if(e.clientX == 0 && e.screenX == 0 && e.layerX > 0) {
  390. distanceX = e.layerX - e.dragStartEventInfo.layerX;
  391. } else {
  392. distanceX = e.clientX - e.dragStartEventInfo.clientX;
  393. }
  394. if(e.clientY == 0 && e.screenY > 0) {
  395. distanceY = e.screenY - e.dragStartEventInfo.screenY;
  396. } else if(e.clientY == 0 && e.screenY == 0 && e.layerY > 0) {
  397. distanceY = e.layerY - e.dragStartEventInfo.layerY;
  398. } else {
  399. distanceY = e.clientY - e.dragStartEventInfo.clientY;
  400. }*/
  401. if(e.clientX == 0 && e.screenX > 0) {
  402. distanceX = e.screenX - e.dragStartEventInfo.screenX;
  403. } else if(e.clientX > 0) {
  404. distanceX = e.clientX - e.dragStartEventInfo.clientX;
  405. }
  406. if(e.clientY == 0 && e.screenY > 0) {
  407. distanceY = e.screenY - e.dragStartEventInfo.screenY;
  408. } else if(e.clientY > 0) {
  409. distanceY = e.clientY - e.dragStartEventInfo.clientY;
  410. }
  411. if(distanceY != 0 || distanceX != 0) {
  412. if(position && position.toLowerCase() == 'fixed') {
  413. var pos = {
  414. top : e.dragStartEventInfo.offsetTargetClientOffset.top + distanceY + 'px',
  415. left : e.dragStartEventInfo.offsetTargetClientOffset.left + distanceX + 'px'
  416. };
  417. $kit.css(e.dragStartEventInfo.offsetTarget, pos);
  418. } else if(position && position.toLowerCase() == 'absolute') {
  419. var pos = {
  420. top : e.dragStartEventInfo.offsetTargetOffset.top + distanceY + 'px',
  421. left : e.dragStartEventInfo.offsetTargetOffset.left + distanceX + 'px'
  422. };
  423. $kit.css(e.dragStartEventInfo.offsetTarget, pos);
  424. }
  425. }
  426. }
  427. },
  428. scope : el
  429. });
  430. me.ev({
  431. el : el,
  432. ev : 'dragend',
  433. fn : function(e, cfg) {
  434. if(e.dragStartEventInfo && e.dragStartEventInfo.offsetTarget != document.body) {
  435. var position = $kit.css(e.dragStartEventInfo.offsetTarget, 'position');
  436. var distanceX = 0, distanceY = 0;
  437. if(e.clientX == 0 && e.screenX > 0) {
  438. distanceX = e.screenX - e.dragStartEventInfo.screenX;
  439. } else {
  440. distanceX = e.clientX - e.dragStartEventInfo.clientX;
  441. }
  442. if(e.clientY == 0 && e.screenY > 0) {
  443. distanceY = e.screenY - e.dragStartEventInfo.screenY;
  444. } else {
  445. distanceY = e.clientY - e.dragStartEventInfo.clientY;
  446. }
  447. if(distanceY != 0 || distanceX != 0) {
  448. if(position && position.toLowerCase() == 'fixed') {
  449. $kit.css(e.dragStartEventInfo.offsetTarget, {
  450. top : e.dragStartEventInfo.offsetTargetClientOffset.top + distanceY + 'px',
  451. left : e.dragStartEventInfo.offsetTargetClientOffset.left + distanceX + 'px'
  452. });
  453. } else if(position && position.toLowerCase() == 'absolute') {
  454. $kit.css(e.dragStartEventInfo.offsetTarget, {
  455. top : e.dragStartEventInfo.offsetTargetOffset.top + distanceY + 'px',
  456. left : e.dragStartEventInfo.offsetTargetOffset.left + distanceX + 'px'
  457. });
  458. }
  459. }
  460. }
  461. },
  462. scope : el
  463. });
  464. },
  465. evExtra : function(ev) {
  466. var me = this;
  467. var re = {};
  468. for(var i = 0; i < $kit.event.eventExtraInfoFnArray.length; i++) {
  469. if($kit.isFn(me.eventExtraInfoFnArray[i])) {
  470. $kit.merge(re, me.eventExtraInfoFnArray[i].call(me, ev));
  471. } else {
  472. $kit.merge(re, me.eventExtraInfoFnArray[i]);
  473. }
  474. }
  475. return re;
  476. },
  477. registExtraEventInfo : function(fn) {
  478. this.eventExtraInfoFnArray.push(fn);
  479. }
  480. });
  481. /**
  482. * $Kit.Event的实例,直接通过这个实例访问$Kit.Event所有方法
  483. * @global
  484. * @type $Kit.Event
  485. */
  486. $kit.event = new $Kit.Event();
  487. /*$kit.ev = function() {
  488. $kit.event.ev.apply($kit.event, arguments);
  489. };*/
  490. $kit.evExtra = function() {
  491. return $Kit.Event.prototype.evExtra.apply($kit.event, arguments);
  492. };