EventHelpers.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. /*******************************************************************************
  2. * This notice must be untouched at all times.
  3. *
  4. * This javascript library contains helper routines to assist with event
  5. * handling consinstently among browsers
  6. *
  7. * EventHelpers.js v.1.3 available at http://www.useragentman.com/
  8. *
  9. * released under the MIT License:
  10. * http://www.opensource.org/licenses/mit-license.php
  11. *
  12. *******************************************************************************/
  13. var EventHelpers = new function(){
  14. var me = this;
  15. var safariTimer;
  16. var isSafari = /WebKit/i.test(navigator.userAgent);
  17. var globalEvent;
  18. me.init = function () {
  19. if (me.hasPageLoadHappened(arguments)) {
  20. return;
  21. }
  22. if (document.createEventObject){
  23. // dispatch for IE
  24. globalEvent = document.createEventObject();
  25. } else if (document.createEvent) {
  26. globalEvent = document.createEvent("HTMLEvents");
  27. }
  28. me.docIsLoaded = true;
  29. }
  30. /**
  31. * Adds an event to the document. Examples of usage:
  32. * me.addEvent(window, "load", myFunction);
  33. * me.addEvent(docunent, "keydown", keyPressedFunc);
  34. * me.addEvent(document, "keyup", keyPressFunc);
  35. *
  36. * @author Scott Andrew - http://www.scottandrew.com/weblog/articles/cbs-events
  37. * @author John Resig - http://ejohn.org/projects/flexible-javascript-events/
  38. * @param {Object} obj - a javascript object.
  39. * @param {String} evType - an event to attach to the object.
  40. * @param {Function} fn - the function that is attached to the event.
  41. */
  42. me.addEvent = function(obj, evType, fn){
  43. if (obj.addEventListener) {
  44. obj.addEventListener(evType, fn, false);
  45. } else if (obj.attachEvent) {
  46. obj['e' + evType + fn] = fn;
  47. obj[evType + fn] = function(){
  48. obj["e" + evType + fn](self.event);
  49. }
  50. obj.attachEvent("on" + evType, obj[evType + fn]);
  51. }
  52. }
  53. /**
  54. * Removes an event that is attached to a javascript object.
  55. *
  56. * @author Scott Andrew - http://www.scottandrew.com/weblog/articles/cbs-events
  57. * @author John Resig - http://ejohn.org/projects/flexible-javascript-events/ * @param {Object} obj - a javascript object.
  58. * @param {String} evType - an event attached to the object.
  59. * @param {Function} fn - the function that is called when the event fires.
  60. */
  61. me.removeEvent = function(obj, evType, fn){
  62. if (obj.removeEventListener) {
  63. obj.removeEventListener(evType, fn, false);
  64. } else if (obj.detachEvent) {
  65. try {
  66. obj.detachEvent("on" + evType, obj[evType + fn]);
  67. obj[evType + fn] = null;
  68. obj["e" + evType + fn] = null;
  69. }
  70. catch (ex) {
  71. // do nothing;
  72. }
  73. }
  74. }
  75. function removeEventAttribute(obj, beginName){
  76. var attributes = obj.attributes;
  77. for (var i = 0; i < attributes.length; i++) {
  78. var attribute = attributes[i]
  79. var name = attribute.name
  80. if (name.indexOf(beginName) == 0) {
  81. //obj.removeAttributeNode(attribute);
  82. attribute.specified = false;
  83. }
  84. }
  85. }
  86. me.addScrollWheelEvent = function(obj, fn){
  87. if (obj.addEventListener) {
  88. /** DOMMouseScroll is for mozilla. */
  89. obj.addEventListener('DOMMouseScroll', fn, true);
  90. }
  91. /** IE/Opera. */
  92. if (obj.attachEvent) {
  93. obj.attachEvent("onmousewheel", fn);
  94. }
  95. }
  96. me.removeScrollWheelEvent = function(obj, fn){
  97. if (obj.removeEventListener) {
  98. /** DOMMouseScroll is for mozilla. */
  99. obj.removeEventListener('DOMMouseScroll', fn, true);
  100. }
  101. /** IE/Opera. */
  102. if (obj.detachEvent) {
  103. obj.detatchEvent("onmousewheel", fn);
  104. }
  105. }
  106. /**
  107. * Given a mouse event, get the mouse pointer's x-coordinate.
  108. *
  109. * @param {Object} e - a DOM Event object.
  110. * @return {int} - the mouse pointer's x-coordinate.
  111. */
  112. me.getMouseX = function(e){
  113. if (!e) {
  114. return;
  115. }
  116. // NS4
  117. if (e.pageX != null) {
  118. return e.pageX;
  119. // IE
  120. } else if (window.event != null && window.event.clientX != null &&
  121. document.body != null &&
  122. document.body.scrollLeft != null)
  123. return window.event.clientX + document.body.scrollLeft;
  124. // W3C
  125. else if (e.clientX != null)
  126. return e.clientX;
  127. else
  128. return null;
  129. }
  130. /**
  131. * Given a mouse event, get the mouse pointer's y-coordinate.
  132. * @param {Object} e - a DOM Event Object.
  133. * @return {int} - the mouse pointer's y-coordinate.
  134. */
  135. me.getMouseY = function(e){
  136. // NS4
  137. if (e.pageY != null)
  138. return e.pageY;
  139. // IE
  140. else if (window.event != null && window.event.clientY != null &&
  141. document.body != null &&
  142. document.body.scrollTop != null)
  143. return window.event.clientY + document.body.scrollTop;
  144. // W3C
  145. else if (e.clientY != null) {
  146. return e.clientY;
  147. }
  148. }
  149. /**
  150. * Given a mouse scroll wheel event, get the "delta" of how fast it moved.
  151. * @param {Object} e - a DOM Event Object.
  152. * @return {int} - the mouse wheel's delta. It is greater than 0, the
  153. * scroll wheel was spun upwards; if less than 0, downwards.
  154. */
  155. me.getScrollWheelDelta = function(e){
  156. var delta = 0;
  157. if (!e) /* For IE. */
  158. e = window.event;
  159. if (e.wheelDelta) { /* IE/Opera. */
  160. delta = e.wheelDelta / 120;
  161. /** In Opera 9, delta differs in sign as compared to IE.
  162. */
  163. if (window.opera) {
  164. delta = -delta;
  165. }
  166. } else if (e.detail) { /** Mozilla case. */
  167. /** In Mozilla, sign of delta is different than in IE.
  168. * Also, delta is multiple of 3.
  169. */
  170. delta = -e.detail / 3;
  171. }
  172. return delta
  173. }
  174. /**
  175. * Sets a mouse move event of a document.
  176. *
  177. * @deprecated - use only if compatibility with IE4 and NS4 is necessary. Otherwise, just
  178. * use EventHelpers.addEvent(window, 'mousemove', func) instead. Cannot be used to add
  179. * multiple mouse move event handlers.
  180. *
  181. * @param {Function} func - the function that you want a mouse event to fire.
  182. */
  183. me.addMouseEvent = function(func){
  184. if (document.captureEvents) {
  185. document.captureEvents(Event.MOUSEMOVE);
  186. }
  187. document.onmousemove = func;
  188. window.onmousemove = func;
  189. window.onmouseover = func;
  190. }
  191. /**
  192. * Find the HTML object that fired an Event.
  193. *
  194. * @param {Object} e - an HTML object
  195. * @return {Object} - the HTML object that fired the event.
  196. */
  197. me.getEventTarget = function(e){
  198. // first, IE method for mouse events(also supported by Safari and Opera)
  199. if (e.toElement) {
  200. return e.toElement;
  201. // W3C
  202. } else if (e.currentTarget) {
  203. return e.currentTarget;
  204. // MS way
  205. } else if (e.srcElement) {
  206. return e.srcElement;
  207. } else {
  208. return null;
  209. }
  210. }
  211. /**
  212. * Given an event fired by the keyboard, find the key associated with that event.
  213. *
  214. * @param {Object} e - an event object.
  215. * @return {String} - the ASCII character code representing the key associated with the event.
  216. */
  217. me.getKey = function(e){
  218. if (e.keyCode) {
  219. return e.keyCode;
  220. } else if (e.event && e.event.keyCode) {
  221. return window.event.keyCode;
  222. } else if (e.which) {
  223. return e.which;
  224. }
  225. }
  226. /**
  227. * Will execute a function when the page's DOM has fully loaded (and before all attached images, iframes,
  228. * etc., are).
  229. *
  230. * Usage:
  231. *
  232. * EventHelpers.addPageLoadEvent('init');
  233. *
  234. * where the function init() has this code at the beginning:
  235. *
  236. * function init() {
  237. *
  238. * if (EventHelpers.hasPageLoadHappened(arguments)) return;
  239. *
  240. * // rest of code
  241. * ....
  242. * }
  243. *
  244. * @author This code is based off of code from http://dean.edwards.name/weblog/2005/09/busted/ by Dean
  245. * Edwards, with a modification by me.
  246. *
  247. * @param {String} funcName - a string containing the function to be called.
  248. */
  249. me.addPageLoadEvent = function(funcName){
  250. var func = eval(funcName);
  251. // for Internet Explorer (using conditional comments)
  252. /*@cc_on @*/
  253. /*@if (@_win32)
  254. pageLoadEventArray.push(func);
  255. return;
  256. /*@end @*/
  257. if (isSafari) { // sniff
  258. pageLoadEventArray.push(func);
  259. if (!safariTimer) {
  260. safariTimer = setInterval(function(){
  261. if (/loaded|complete/.test(document.readyState)) {
  262. clearInterval(safariTimer);
  263. /*
  264. * call the onload handler
  265. * func();
  266. */
  267. me.runPageLoadEvents();
  268. return;
  269. }
  270. set = true;
  271. }, 10);
  272. }
  273. /* for Mozilla */
  274. } else if (document.addEventListener) {
  275. var x = document.addEventListener("DOMContentLoaded", func, null);
  276. /* Others */
  277. } else {
  278. me.addEvent(window, 'load', func);
  279. }
  280. }
  281. var pageLoadEventArray = new Array();
  282. me.runPageLoadEvents = function(e){
  283. if (isSafari || e.srcElement.readyState == "complete") {
  284. for (var i = 0; i < pageLoadEventArray.length; i++) {
  285. pageLoadEventArray[i]();
  286. }
  287. }
  288. }
  289. /**
  290. * Determines if either addPageLoadEvent('funcName') or addEvent(window, 'load', funcName)
  291. * has been executed.
  292. *
  293. * @see addPageLoadEvent
  294. * @param {Function} funcArgs - the arguments of the containing. function
  295. */
  296. me.hasPageLoadHappened = function(funcArgs){
  297. // If the function already been called, return true;
  298. if (funcArgs.callee.done)
  299. return true;
  300. // flag this function so we don't do the same thing twice
  301. funcArgs.callee.done = true;
  302. }
  303. /**
  304. * Used in an event method/function to indicate that the default behaviour of the event
  305. * should *not* happen.
  306. *
  307. * @param {Object} e - an event object.
  308. * @return {Boolean} - always false
  309. */
  310. me.preventDefault = function(e){
  311. if (e.preventDefault) {
  312. e.preventDefault();
  313. }
  314. try {
  315. e.returnValue = false;
  316. }
  317. catch (ex) {
  318. // do nothing
  319. }
  320. }
  321. me.cancelBubble = function(e){
  322. if (e.stopPropagation) {
  323. e.stopPropagation();
  324. }
  325. try {
  326. e.cancelBubble = true;
  327. }
  328. catch (ex) {
  329. // do nothing
  330. }
  331. }
  332. /*
  333. * Fires an event manually.
  334. * @author Scott Andrew - http://www.scottandrew.com/weblog/articles/cbs-events
  335. * @author John Resig - http://ejohn.org/projects/flexible-javascript-events/ * @param {Object} obj - a javascript object.
  336. * @param {String} evType - an event attached to the object.
  337. * @param {Function} fn - the function that is called when the event fires.
  338. *
  339. */
  340. me.fireEvent = function (element,event, options){
  341. if(!element) {
  342. return;
  343. }
  344. if (document.createEventObject){
  345. /*
  346. var stack = DebugHelpers.getStackTrace();
  347. var s = stack.toString();
  348. jslog.debug(s);
  349. if (s.indexOf('fireEvent') >= 0) {
  350. return;
  351. }
  352. */
  353. return element.fireEvent('on' + event, globalEvent)
  354. jslog.debug('ss');
  355. }
  356. else{
  357. // dispatch for firefox + others
  358. globalEvent.initEvent(event, true, true); // event type,bubbling,cancelable
  359. return !element.dispatchEvent(globalEvent);
  360. }
  361. }
  362. /* EventHelpers.init () */
  363. function init(){
  364. // Conditional comment alert: Do not remove comments. Leave intact.
  365. // The detection if the page is secure or not is important. If
  366. // this logic is removed, Internet Explorer will give security
  367. // alerts.
  368. /*@cc_on @*/
  369. /*@if (@_win32)
  370. document.write('<script id="__ie_onload" defer src="' +
  371. ((location.protocol == 'https:') ? '//0' : 'javascript:void(0)') + '"><\/script>');
  372. var script = document.getElementById("__ie_onload");
  373. me.addEvent(script, 'readystatechange', me.runPageLoadEvents);
  374. /*@end @*/
  375. }
  376. init();
  377. }
  378. EventHelpers.addPageLoadEvent('EventHelpers.init');