/ Published in: Other
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
/** * Initializes expanders on this page after the document has been loaded */ YAHOO.util.Event.onDOMReady(function() { // remember link location var hash = location.hash; var expanders = YAHOO.util.Dom.getElementsByClassName('expander'); for (var i = 0; i < expanders.length; i++) { new Mozilla.Expander(expanders[i]); } // reset link location since the link may have moved on the page if (hash) { if ((/safari/gi).test(navigator.userAgent)) { location.hash = '#nothing'; /* Safari hack */ } location.hash = hash; } }); // create namespace if (typeof Mozilla == 'undefined') { function Mozilla() {} } /** * Expander widget * * @param DOMElement container */ Mozilla.Expander = function(container) { if (typeof container == 'String') { container = YAHOO.util.Dom.get(container); } // get header and content elements as first two child elements var header = YAHOO.util.Dom.getFirstChild(container); this.content = YAHOO.util.Dom.getNextSibling(header); this.container = container; if (!this.container.id) { YAHOO.util.Dom.generateId(this.container, 'mozilla-expander-'); } this.id = this.container.id; // build header markup this.anchor = document.createElement('a'); this.anchor.href = '#'; this.anchor.className = 'expander-anchor'; while (header.firstChild) { this.anchor.appendChild(header.firstChild); } header.appendChild(this.anchor); YAHOO.util.Event.on(this.anchor, 'click', function(e) { YAHOO.util.Event.preventDefault(e); this.toggleWithAnimation(); }, this, true); // build content markup this.content_animation = document.createElement('div'); this.content_animation.className = 'expander-animation'; var content_padding = document.createElement('div'); content_padding.className = 'expander-padding'; while (this.content.firstChild) { content_padding.appendChild(this.content.firstChild); } this.content_animation.appendChild(content_padding); this.content.appendChild(this.content_animation); // prevent closing during opening animation and vice versa this.semaphore = false; YAHOO.util.Dom.removeClass(this.container, 'expander'); if ((location.hash.substring(1) == this.id) || this.loadState() == Mozilla.Expander.OPEN) { this.open(); } else { this.close(); } } Mozilla.Expander.OPEN = true; Mozilla.Expander.CLOSED = false; Mozilla.Expander.OPEN_DURATION = 0.25; Mozilla.Expander.CLOSE_DURATION = 0.25; Mozilla.Expander.OPEN_TEXT = 'Show'; Mozilla.Expander.CLOSE_TEXT = 'Hide'; Mozilla.Expander.prototype.toggle = function(e) { if (this.state == Mozilla.Expander.OPEN) { this.close(); } else { this.open(); } } Mozilla.Expander.prototype.saveState = function() { if (typeof sessionStorage != 'undefined') { var href = location.href.split('#')[0]; var state = (this.state == Mozilla.Expander.OPEN) ? 'open' : 'closed'; sessionStorage.setItem(href + '-' + this.id, state); } } Mozilla.Expander.prototype.loadState = function() { var state = Mozilla.Expander.CLOSED; if (typeof sessionStorage != 'undefined') { var href = location.href.split('#')[0]; var loaded_state = sessionStorage.getItem(href + '-' + this.id); if (loaded_state !== null) { state = (loaded_state == 'open') ? Mozilla.Expander.OPEN : Mozilla.Expander.CLOSED; } } return state; } Mozilla.Expander.prototype.toggleWithAnimation = function(e) { if (this.state == Mozilla.Expander.OPEN) { this.closeWithAnimation(); } else { this.openWithAnimation(); } } Mozilla.Expander.prototype.openWithAnimation = function() { if (this.semaphore) return; YAHOO.util.Dom.removeClass(this.container, 'expander-closed'); YAHOO.util.Dom.addClass(this.container, 'expander-open'); // get display height this.content_animation.parentNode.style.overflow = 'hidden'; this.content_animation.parentNode.style.height = '0'; this.content_animation.style.visibility = 'hidden'; this.content_animation.style.overflow = 'hidden'; this.content_animation.style.display = 'block'; this.content_animation.style.height = 'auto'; var height = this.content_animation.offsetHeight; this.content_animation.style.height = '0'; this.content_animation.style.visibility = 'visible'; this.content_animation.parentNode.style.height = ''; this.content_animation.parentNode.style.overflow = 'visible'; var attributes = { height: { to: height, from: 0 } }; var animation = new YAHOO.util.Anim(this.content_animation, attributes, Mozilla.Expander.OPEN_DURATION, YAHOO.util.Easing.easeOut); this.semaphore = true; animation.onComplete.subscribe(this.handleOpen, this, true); animation.animate(); this.state = Mozilla.Expander.OPEN; } Mozilla.Expander.prototype.closeWithAnimation = function() { if (this.semaphore) return; this.content_animation.style.overflow = 'hidden'; this.content_animation.style.height = 'auto'; var attributes = { height: { to: 0 } }; var animation = new YAHOO.util.Anim(this.content_animation, attributes, Mozilla.Expander.CLOSE_DURATION, YAHOO.util.Easing.easeOut); this.semaphore = true; animation.onComplete.subscribe(this.handleClose, this, true); animation.animate(); this.state = Mozilla.Expander.CLOSED; } Mozilla.Expander.prototype.open = function() { YAHOO.util.Dom.removeClass(this.container, 'expander-closed'); YAHOO.util.Dom.addClass(this.container, 'expander-open'); this.semaphore = false; this.state = Mozilla.Expander.OPEN; this.anchor.title = Mozilla.Expander.CLOSE_TEXT; this.saveState(); } Mozilla.Expander.prototype.close = function() { YAHOO.util.Dom.removeClass(this.container, 'expander-opened'); YAHOO.util.Dom.addClass(this.container, 'expander-closed'); this.semaphore = false; this.state = Mozilla.Expander.CLOSED; this.anchor.title = Mozilla.Expander.OPEN_TEXT; this.saveState(); } Mozilla.Expander.prototype.handleOpen = function() { // allow font resizing to work again this.content_animation.style.height = 'auto'; // re-set overflow to visible for styles that might depend on it this.content_animation.style.overflow = 'visible'; this.anchor.title = Mozilla.Expander.CLOSE_TEXT; this.semaphore = false; this.saveState(); } Mozilla.Expander.prototype.handleClose = function() { YAHOO.util.Dom.removeClass(this.container, 'expander-open'); YAHOO.util.Dom.addClass(this.container, 'expander-closed'); this.anchor.title = Mozilla.Expander.OPEN_TEXT; this.semaphore = false; this.saveState(); }