menu.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*
  2. Author: mg12
  3. Update: 2009/08/07
  4. Author URI: http://www.neoease.com/
  5. */
  6. (function() {
  7. var Class = {
  8. create: function() {
  9. return function() {
  10. this.initialize.apply(this, arguments);
  11. }
  12. }
  13. }
  14. var GhostlyMenu = Class.create();
  15. GhostlyMenu.prototype = {
  16. initialize: function(target, align, sub) {
  17. this.obj = cleanWhitespace(target);
  18. this.align = align || 'left';
  19. this.sub = sub || -1;
  20. this.menu = this.obj.childNodes;
  21. if (this.menu.length < 2) { return; }
  22. this.title = this.menu[0];
  23. this.body = this.menu[1];
  24. cleanWhitespace(this.body).lastChild.getElementsByTagName('a')[0].className += ' last';
  25. setStyle(this.body, 'visibility', 'hidden');
  26. setStyle(this.body, 'display', 'block');
  27. addListener(this.obj, 'mouseover', bind(this, this.activate), false);
  28. addListener(this.obj, 'mouseout', bind(this, this.deactivate), false);
  29. },
  30. activate: function() {
  31. if(this.sub == 1) {
  32. var pos = currentOffset(this.title);
  33. var top = pos[1] - 1;
  34. var left = getWidth(this.body) - 2;
  35. if (this.align == 'right') {
  36. var left = getWidth(this.body) * (-1);
  37. }
  38. } else {
  39. var pos = cumulativeOffset(this.title);
  40. var top = pos[1] + getHeight(this.title);
  41. var left = pos[0];
  42. if (this.align == 'right') {
  43. left += getWidth(this.title) - getWidth(this.body);
  44. }
  45. }
  46. if(!/current/.test(this.title.className)) {
  47. this.title.className += ' current';
  48. }
  49. setStyle(this.body, 'left', left + 'px');
  50. setStyle(this.body, 'top', top + 'px');
  51. setStyle(this.body, 'visibility', 'visible');
  52. },
  53. deactivate: function(){
  54. this.title.className = this.title.className.replace('current', '');
  55. var thismenu = this;
  56. var tid = setInterval( function() {
  57. clearInterval(tid);
  58. if (!/current/.test(thismenu.title.className)) {
  59. setStyle(thismenu.body, 'visibility', 'hidden');
  60. }
  61. return false;
  62. }, 400);
  63. }
  64. }
  65. $A = function(iterable) {
  66. if(!iterable) {
  67. return [];
  68. }
  69. if(iterable.toArray) {
  70. return iterable.toArray();
  71. } else {
  72. var results = [];
  73. for(var i = 0; i < iterable.length; i++) {
  74. results.push(iterable[i]);
  75. }
  76. return results;
  77. }
  78. }
  79. bind = function() {
  80. var array = this.$A(arguments);
  81. var func = array[array.length - 1];
  82. var method = func, args = array, object = args.shift();
  83. return function() {
  84. return method.apply(object, args.concat(array));
  85. }
  86. }
  87. getHeight = function(element) {
  88. return element.offsetHeight;
  89. }
  90. getWidth = function(element) {
  91. return element.offsetWidth;
  92. }
  93. setStyle = function(element, key, value) {
  94. element.style[key] = value;
  95. }
  96. cleanWhitespace = function(list) {
  97. var node = list.firstChild;
  98. while (node) {
  99. var nextNode = node.nextSibling;
  100. if(node.nodeType == 3 && !/\S/.test(node.nodeValue)) {
  101. list.removeChild(node);
  102. }
  103. node = nextNode;
  104. }
  105. return list;
  106. }
  107. currentOffset = function(element) {
  108. var valueT = element.offsetTop || 0;
  109. var valueL = element.offsetLeft || 0;
  110. return [valueL, valueT];
  111. }
  112. cumulativeOffset = function(element) {
  113. var valueT = 0, valueL = 0;
  114. do {
  115. valueT += element.offsetTop || 0;
  116. valueL += element.offsetLeft || 0;
  117. element = element.offsetParent;
  118. } while (element);
  119. return [valueL, valueT];
  120. }
  121. addListener = function(element, name, observer, useCapture) {
  122. if(element.addEventListener) {
  123. element.addEventListener(name, observer, useCapture);
  124. } else if(element.attachEvent) {
  125. element.attachEvent('on' + name, observer);
  126. }
  127. }
  128. function loadMenus() {
  129. var align = 'left';
  130. for(var i = 0; (a = document.getElementsByTagName('link')[i]); i++) {
  131. if((a.getAttribute('rel') == 'stylesheet') && (a.getAttribute('href').indexOf('rtl.css') != -1)) {
  132. align = 'right';
  133. }
  134. }
  135. var subscribe = document.getElementById('subscribe');
  136. if (subscribe) {
  137. new GhostlyMenu(subscribe, align);
  138. }
  139. var menubar = document.getElementById('menus');
  140. if (menubar) {
  141. var list = menubar.getElementsByTagName('ul');
  142. for (var i = 0; i < list.length; i++) {
  143. var menu = list[i].parentNode;
  144. if(menu.parentNode === menubar) {
  145. new GhostlyMenu(menu, align);
  146. } else {
  147. new GhostlyMenu(menu, align, 1);
  148. menu.firstChild.className += ' subtitle';
  149. }
  150. }
  151. }
  152. }
  153. if (document.addEventListener) {
  154. document.addEventListener("DOMContentLoaded", loadMenus, false);
  155. } else if (/MSIE/i.test(navigator.userAgent)) {
  156. document.write('<script id="__ie_onload_for_inove" defer src="javascript:void(0)"></script>');
  157. var script = document.getElementById('__ie_onload_for_inove');
  158. script.onreadystatechange = function() {
  159. if (this.readyState == 'complete') {
  160. loadMenus();
  161. }
  162. }
  163. } else if (/WebKit/i.test(navigator.userAgent)) {
  164. var _timer = setInterval( function() {
  165. if (/loaded|complete/.test(document.readyState)) {
  166. clearInterval(_timer);
  167. loadMenus();
  168. }
  169. }, 10);
  170. } else {
  171. window.onload = function(e) {
  172. loadMenus();
  173. }
  174. }
  175. })();