Posted By

johnloy on 06/18/08


Tagged

javascript textmate yui accordion expander


Versions (?)

Mozilla expander


 / Published in: Other
 

  1. /**
  2. * Initializes expanders on this page after the document has been loaded
  3. */
  4. YAHOO.util.Event.onDOMReady(function()
  5. {
  6. // remember link location
  7. var hash = location.hash;
  8.  
  9. var expanders = YAHOO.util.Dom.getElementsByClassName('expander');
  10. for (var i = 0; i < expanders.length; i++) {
  11. new Mozilla.Expander(expanders[i]);
  12. }
  13.  
  14. // reset link location since the link may have moved on the page
  15. if (hash) {
  16. if ((/safari/gi).test(navigator.userAgent)) {
  17. location.hash = '#nothing'; /* Safari hack */
  18. }
  19. location.hash = hash;
  20. }
  21. });
  22.  
  23. // create namespace
  24. if (typeof Mozilla == 'undefined') {
  25. function Mozilla() {}
  26. }
  27.  
  28. /**
  29. * Expander widget
  30. *
  31. * @param DOMElement container
  32. */
  33. Mozilla.Expander = function(container)
  34. {
  35. if (typeof container == 'String') {
  36. container = YAHOO.util.Dom.get(container);
  37. }
  38.  
  39. // get header and content elements as first two child elements
  40. var header = YAHOO.util.Dom.getFirstChild(container);
  41. this.content = YAHOO.util.Dom.getNextSibling(header);
  42. this.container = container;
  43.  
  44. if (!this.container.id) {
  45. YAHOO.util.Dom.generateId(this.container, 'mozilla-expander-');
  46. }
  47.  
  48. this.id = this.container.id;
  49.  
  50. // build header markup
  51. this.anchor = document.createElement('a');
  52. this.anchor.href = '#';
  53. this.anchor.className = 'expander-anchor';
  54. while (header.firstChild) {
  55. this.anchor.appendChild(header.firstChild);
  56. }
  57. header.appendChild(this.anchor);
  58.  
  59. YAHOO.util.Event.on(this.anchor, 'click',
  60. function(e)
  61. {
  62. YAHOO.util.Event.preventDefault(e);
  63. this.toggleWithAnimation();
  64. },
  65. this, true);
  66.  
  67. // build content markup
  68. this.content_animation = document.createElement('div');
  69. this.content_animation.className = 'expander-animation';
  70.  
  71. var content_padding = document.createElement('div');
  72. content_padding.className = 'expander-padding';
  73. while (this.content.firstChild) {
  74. content_padding.appendChild(this.content.firstChild);
  75. }
  76. this.content_animation.appendChild(content_padding);
  77.  
  78. this.content.appendChild(this.content_animation);
  79.  
  80. // prevent closing during opening animation and vice versa
  81. this.semaphore = false;
  82.  
  83. YAHOO.util.Dom.removeClass(this.container, 'expander');
  84.  
  85. if ((location.hash.substring(1) == this.id) ||
  86. this.loadState() == Mozilla.Expander.OPEN) {
  87. this.open();
  88. } else {
  89. this.close();
  90. }
  91. }
  92.  
  93. Mozilla.Expander.OPEN = true;
  94. Mozilla.Expander.CLOSED = false;
  95. Mozilla.Expander.OPEN_DURATION = 0.25;
  96. Mozilla.Expander.CLOSE_DURATION = 0.25;
  97.  
  98. Mozilla.Expander.OPEN_TEXT = 'Show';
  99. Mozilla.Expander.CLOSE_TEXT = 'Hide';
  100.  
  101. Mozilla.Expander.prototype.toggle = function(e)
  102. {
  103. if (this.state == Mozilla.Expander.OPEN) {
  104. this.close();
  105. } else {
  106. this.open();
  107. }
  108. }
  109.  
  110. Mozilla.Expander.prototype.saveState = function()
  111. {
  112. if (typeof sessionStorage != 'undefined') {
  113. var href = location.href.split('#')[0];
  114. var state = (this.state == Mozilla.Expander.OPEN) ?
  115. 'open' : 'closed';
  116.  
  117. sessionStorage.setItem(href + '-' + this.id, state);
  118. }
  119. }
  120.  
  121. Mozilla.Expander.prototype.loadState = function()
  122. {
  123. var state = Mozilla.Expander.CLOSED;
  124. if (typeof sessionStorage != 'undefined') {
  125. var href = location.href.split('#')[0];
  126. var loaded_state = sessionStorage.getItem(href + '-' + this.id);
  127. if (loaded_state !== null) {
  128. state = (loaded_state == 'open') ?
  129. Mozilla.Expander.OPEN : Mozilla.Expander.CLOSED;
  130. }
  131. }
  132. return state;
  133. }
  134.  
  135. Mozilla.Expander.prototype.toggleWithAnimation = function(e)
  136. {
  137. if (this.state == Mozilla.Expander.OPEN) {
  138. this.closeWithAnimation();
  139. } else {
  140. this.openWithAnimation();
  141. }
  142. }
  143.  
  144. Mozilla.Expander.prototype.openWithAnimation = function()
  145. {
  146. if (this.semaphore)
  147. return;
  148.  
  149. YAHOO.util.Dom.removeClass(this.container, 'expander-closed');
  150. YAHOO.util.Dom.addClass(this.container, 'expander-open');
  151.  
  152. // get display height
  153. this.content_animation.parentNode.style.overflow = 'hidden';
  154. this.content_animation.parentNode.style.height = '0';
  155. this.content_animation.style.visibility = 'hidden';
  156. this.content_animation.style.overflow = 'hidden';
  157. this.content_animation.style.display = 'block';
  158. this.content_animation.style.height = 'auto';
  159. var height = this.content_animation.offsetHeight;
  160. this.content_animation.style.height = '0';
  161. this.content_animation.style.visibility = 'visible';
  162. this.content_animation.parentNode.style.height = '';
  163. this.content_animation.parentNode.style.overflow = 'visible';
  164.  
  165. var attributes = { height: { to: height, from: 0 } };
  166. var animation = new YAHOO.util.Anim(this.content_animation, attributes,
  167. Mozilla.Expander.OPEN_DURATION,
  168. YAHOO.util.Easing.easeOut);
  169.  
  170. this.semaphore = true;
  171. animation.onComplete.subscribe(this.handleOpen, this, true);
  172. animation.animate();
  173.  
  174. this.state = Mozilla.Expander.OPEN;
  175. }
  176.  
  177. Mozilla.Expander.prototype.closeWithAnimation = function()
  178. {
  179. if (this.semaphore)
  180. return;
  181.  
  182. this.content_animation.style.overflow = 'hidden';
  183. this.content_animation.style.height = 'auto';
  184. var attributes = { height: { to: 0 } };
  185. var animation = new YAHOO.util.Anim(this.content_animation, attributes,
  186. Mozilla.Expander.CLOSE_DURATION,
  187. YAHOO.util.Easing.easeOut);
  188.  
  189. this.semaphore = true;
  190. animation.onComplete.subscribe(this.handleClose, this, true);
  191. animation.animate();
  192.  
  193. this.state = Mozilla.Expander.CLOSED;
  194. }
  195.  
  196. Mozilla.Expander.prototype.open = function()
  197. {
  198. YAHOO.util.Dom.removeClass(this.container, 'expander-closed');
  199. YAHOO.util.Dom.addClass(this.container, 'expander-open');
  200.  
  201. this.semaphore = false;
  202.  
  203. this.state = Mozilla.Expander.OPEN;
  204. this.anchor.title = Mozilla.Expander.CLOSE_TEXT;
  205.  
  206. this.saveState();
  207. }
  208.  
  209. Mozilla.Expander.prototype.close = function()
  210. {
  211. YAHOO.util.Dom.removeClass(this.container, 'expander-opened');
  212. YAHOO.util.Dom.addClass(this.container, 'expander-closed');
  213.  
  214. this.semaphore = false;
  215.  
  216. this.state = Mozilla.Expander.CLOSED;
  217. this.anchor.title = Mozilla.Expander.OPEN_TEXT;
  218.  
  219. this.saveState();
  220. }
  221.  
  222. Mozilla.Expander.prototype.handleOpen = function()
  223. {
  224. // allow font resizing to work again
  225. this.content_animation.style.height = 'auto';
  226.  
  227. // re-set overflow to visible for styles that might depend on it
  228. this.content_animation.style.overflow = 'visible';
  229.  
  230. this.anchor.title = Mozilla.Expander.CLOSE_TEXT;
  231.  
  232. this.semaphore = false;
  233.  
  234. this.saveState();
  235. }
  236.  
  237. Mozilla.Expander.prototype.handleClose = function()
  238. {
  239. YAHOO.util.Dom.removeClass(this.container, 'expander-open');
  240. YAHOO.util.Dom.addClass(this.container, 'expander-closed');
  241.  
  242. this.anchor.title = Mozilla.Expander.OPEN_TEXT;
  243.  
  244. this.semaphore = false;
  245.  
  246. this.saveState();
  247. }
  248.  

Report this snippet  

Comments

RSS Icon Subscribe to comments
Posted By: codemaster on May 2, 2009

The problem is: HOW do you use it? Can you please tell me?

You need to login to post a comment.