accordion.html
<!DOCTYPE html><html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>自動調整面板</title> <link href="pages/accord1/accordion.css" type="text/css" rel="stylesheet"> <script src="pages/accord1/accordion.js" type="text/javascript"></script> </head> <body> <div id="Accordion1" class="Accordion" tabindex="0"> <div class="AccordionPanel"> <div class="AccordionPanelTab top">Home</div> <div class="AccordionPanelContent"><img src="cup.gif"> <p>An anchor tag can be used inside of a Collapsible Panel Tab so that the key board focus ring appears *inside* the tab instead of around the tab. This is an example of how to make the text within the anchor tag look like non-anchor (normal) text.This is an example of how to change the appearance of the panel tab that is currently open. The class "CollapsiblePanelOpen" is programatically added and removed from panel.</p> </div> </div> <div class="AccordionPanel"> <div class="AccordionPanelTab">Web Design</div> <div class="AccordionPanelContent">An anchor tag can be used inside of a Collapsible Panel Tab so that the key board focus ring appears *inside* the tab instead of around the tab. This is an example of how to make the text within the anchor tag look like non-anchor (normal) text.This is an example of how to change the appearance of the panel tab that is currently open. The class "CollapsiblePanelOpen" is programatically added and removed from panels as the user clicks on the tabs within the CollapsiblePanel. on the tabs within the CollapsiblePanel </div> </div> <div class="AccordionPanel"> <div class="AccordionPanelTab">Web Dev</div> <div class="AccordionPanelContent">An anchor tag can be used inside of a Collapsible Panel Tab so that the key board focus ring appears *inside* the tab instead of around the tab. This is an example of how to make the text within the anchor tag look like non-anchor (normal) text.This is an example of how to change the appearance of the panel tab that is currently open. The class "CollapsiblePanelOpen" is programatically added and removed from panels as the user clicks on the tabs within the CollapsiblePanel. on the tabs within the CollapsiblePanel </div> </div> <div class="AccordionPanel"> <div class="AccordionPanelTab">Map</div> <div class="AccordionPanelContent">An anchor tag can be used inside of a Collapsible Panel Tab so that the key board focus ring appears *inside* the tab instead of around the tab. This is an example of how to make the text within the anchor tag look like non-anchor (normal) text.This is an example of how to change the appearance of the panel tab that is currently open. The class "CollapsiblePanelOpen" is programatically added and removed from panels as the user clicks on the tabs within the CollapsiblePanel. on the tabs within the CollapsiblePanel </div> </div> </div> <script type="text/javascript"> var Accordion1 = new Spry.Widget.Accordion("Accordion1"); </script> </body></html>
accordion.css
@charset "UTF-8";.Accordion { width:300px; overflow: hidden; border-bottom:2px #006 solid;}.AccordionPanel { margin: 0px; padding: 0px;}.AccordionPanelTab { background: url(ac-open-back.gif) no-repeat; font: bold 16px Arial; color:#006; line-height:30px; height:30px; margin: 0px; padding: 0px 30px; cursor: pointer; -moz-user-select: none; -khtml-user-select: none;}.top{ background: url(ac-open-back-top.gif) no-repeat;}.AccordionPanelContent { background:#ADF; font:12px/18px Arial; overflow: auto; margin: 0px; padding: 0 10px; height: 230px; border-left:2px #006 solid; border-right:2px #006 solid;}.AccordionPanelContent img{ float:left; padding:2px; margin:2px; border:1px #aaa dashed;}.AccordionPanelOpen .AccordionPanelTab { background: url(ac-open-back-open.gif) no-repeat;}.AccordionPanelOpen .top { background: url(ac-open-back-top-open.gif) no-repeat;}
accordion.js
var Spry;if (!Spry) Spry = {};if (!Spry.Widget) Spry.Widget = {};Spry.Widget.Accordion = function(element, opts){ this.element = this.getElement(element); this.defaultPanel = 0; this.hoverClass = "AccordionPanelTabHover"; this.openClass = "AccordionPanelOpen"; this.closedClass = "AccordionPanelClosed"; this.focusedClass = "AccordionFocused"; this.enableAnimation = true; this.enableKeyboardNavigation = true; this.currentPanel = null; this.animator = null; this.hasFocus = null; this.duration = 100; this.previousPanelKeyCode = Spry.Widget.Accordion.KEY_UP; this.nextPanelKeyCode = Spry.Widget.Accordion.KEY_DOWN; this.useFixedPanelHeights = true; this.fixedPanelHeight = 0; Spry.Widget.Accordion.setOptions(this, opts, true); if (Spry.Widget.Accordion.onloadDidFire) this.attachBehaviors(); else Spry.Widget.Accordion.loadQueue.push(this);};Spry.Widget.Accordion.onloadDidFire = false;Spry.Widget.Accordion.loadQueue = [];Spry.Widget.Accordion.addLoadListener = function(handler){ if (typeof window.addEventListener != 'undefined') window.addEventListener('load', handler, false); else if (typeof document.addEventListener != 'undefined') document.addEventListener('load', handler, false); else if (typeof window.attachEvent != 'undefined') window.attachEvent('onload', handler);};Spry.Widget.Accordion.processLoadQueue = function(handler){ Spry.Widget.Accordion.onloadDidFire = true; var q = Spry.Widget.Accordion.loadQueue; var qlen = q.length; for (var i = 0; i < qlen; i++) q[i].attachBehaviors();};Spry.Widget.Accordion.addLoadListener(Spry.Widget.Accordion.processLoadQueue);Spry.Widget.Accordion.prototype.getElement = function(ele){ if (ele && typeof ele == "string") return document.getElementById(ele); return ele;};Spry.Widget.Accordion.prototype.addClassName = function(ele, className){ if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1)) return; ele.className += (ele.className ? " " : "") + className;};Spry.Widget.Accordion.prototype.removeClassName = function(ele, className){ if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) == -1)) return; ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");};Spry.Widget.Accordion.setOptions = function(obj, optionsObj, ignoreUndefinedProps){ if (!optionsObj) return; for (var optionName in optionsObj) { if (ignoreUndefinedProps && optionsObj[optionName] == undefined) continue; obj[optionName] = optionsObj[optionName]; }};Spry.Widget.Accordion.prototype.onPanelTabMouseOver = function(panel){ if (panel) this.addClassName(this.getPanelTab(panel), this.hoverClass);};Spry.Widget.Accordion.prototype.onPanelTabMouseOut = function(panel){ if (panel) this.removeClassName(this.getPanelTab(panel), this.hoverClass);};Spry.Widget.Accordion.prototype.openPanel = function(panel){ var panelA = this.currentPanel; var panelB = panel; if (!panelB || panelA == panelB) return; var contentA; if( panelA ) contentA = this.getPanelContent(panelA); var contentB = this.getPanelContent(panelB); if (! contentB) return; if (this.useFixedPanelHeights && !this.fixedPanelHeight) { this.fixedPanelHeight = (contentA.offsetHeight) ? contentA.offsetHeight : contentA.scrollHeight; } if (this.enableAnimation) { if (this.animator) this.animator.stop(); this.animator = new Spry.Widget.Accordion.PanelAnimator(this, panelB, { duration: this.duration }); this.animator.start(); } else { if(contentA) contentA.style.height = "0px"; contentB.style.height = (this.useFixedPanelHeights ? this.fixedPanelHeight : contentB.scrollHeight) + "px"; } if(panelA) { this.removeClassName(panelA, this.openClass); this.addClassName(panelA, this.closedClass); } this.removeClassName(panelB, this.closedClass); this.addClassName(panelB, this.openClass); this.currentPanel = panelB;};Spry.Widget.Accordion.prototype.openNextPanel = function(){ var panels = this.getPanels(); var curPanelIndex = this.getCurrentPanelIndex(); if( panels && curPanelIndex >= 0 && (curPanelIndex+1) < panels.length ) this.openPanel(panels[curPanelIndex+1]);};Spry.Widget.Accordion.prototype.openPreviousPanel = function(){ var panels = this.getPanels(); var curPanelIndex = this.getCurrentPanelIndex(); if( panels && curPanelIndex > 0 && curPanelIndex < panels.length ) this.openPanel(panels[curPanelIndex-1]);};Spry.Widget.Accordion.prototype.openFirstPanel = function(){ var panels = this.getPanels(); if( panels ) this.openPanel(panels[0]);};Spry.Widget.Accordion.prototype.openLastPanel = function(){ var panels = this.getPanels(); if( panels ) this.openPanel(panels[panels.length-1]);};Spry.Widget.Accordion.prototype.onPanelClick = function(panel){ // if (this.enableKeyboardNavigation) // this.element.focus(); if (panel != this.currentPanel) this.openPanel(panel); this.focus();};Spry.Widget.Accordion.prototype.onFocus = function(e){ // this.element.focus(); this.hasFocus = true; this.addClassName(this.element, this.focusedClass);};Spry.Widget.Accordion.prototype.onBlur = function(e){ // this.element.blur(); this.hasFocus = false; this.removeClassName(this.element, this.focusedClass);};Spry.Widget.Accordion.KEY_UP = 38;Spry.Widget.Accordion.KEY_DOWN = 40;Spry.Widget.Accordion.prototype.onKeyDown = function(e){ var key = e.keyCode; if (!this.hasFocus || (key != this.previousPanelKeyCode && key != this.nextPanelKeyCode)) return true; var panels = this.getPanels(); if (!panels || panels.length < 1) return false; var currentPanel = this.currentPanel ? this.currentPanel : panels[0]; var nextPanel = (key == this.nextPanelKeyCode) ? currentPanel.nextSibling : currentPanel.previousSibling; while (nextPanel) { if (nextPanel.nodeType == 1 /* Node.ELEMENT_NODE */) break; nextPanel = (key == this.nextPanelKeyCode) ? nextPanel.nextSibling : nextPanel.previousSibling; } if (nextPanel && currentPanel != nextPanel) this.openPanel(nextPanel); if (e.stopPropagation) e.stopPropagation(); if (e.preventDefault) e.preventDefault(); return false;};Spry.Widget.Accordion.prototype.attachPanelHandlers = function(panel){ if (!panel) return; var tab = this.getPanelTab(panel); if (tab) { var self = this; Spry.Widget.Accordion.addEventListener(tab, "click", function(e) { return self.onPanelClick(panel); }, false); Spry.Widget.Accordion.addEventListener(tab, "mouseover", function(e) { return self.onPanelTabMouseOver(panel); }, false); Spry.Widget.Accordion.addEventListener(tab, "mouseout", function(e) { return self.onPanelTabMouseOut(panel); }, false); }};Spry.Widget.Accordion.addEventListener = function(element, eventType, handler, capture){ try { if (element.addEventListener) element.addEventListener(eventType, handler, capture); else if (element.attachEvent) element.attachEvent("on" + eventType, handler); } catch (e) {}};Spry.Widget.Accordion.prototype.initPanel = function(panel, isDefault){ var content = this.getPanelContent(panel); if (isDefault) { this.currentPanel = panel; this.removeClassName(panel, this.closedClass); this.addClassName(panel, this.openClass); } else { this.removeClassName(panel, this.openClass); this.addClassName(panel, this.closedClass); content.style.height = "0px"; } this.attachPanelHandlers(panel);};Spry.Widget.Accordion.prototype.attachBehaviors = function(){ var panels = this.getPanels(); for (var i = 0; i < panels.length; i++) { this.initPanel(panels[i], i == this.defaultPanel); } if (this.enableKeyboardNavigation) { // XXX: IE doesn't allow the setting of tabindex dynamically. This means we can't // rely on adding the tabindex attribute if it is missing to enable keyboard navigation // by default. var tabIndexAttr = this.element.attributes.getNamedItem("tabindex"); // if (!tabIndexAttr) this.element.tabindex = 0; if (tabIndexAttr) { var self = this; Spry.Widget.Accordion.addEventListener(this.element, "focus", function(e) { return self.onFocus(e); }, false); Spry.Widget.Accordion.addEventListener(this.element, "blur", function(e) { return self.onBlur(e); }, false); Spry.Widget.Accordion.addEventListener(this.element, "keydown", function(e) { return self.onKeyDown(e); }, false); } }};Spry.Widget.Accordion.prototype.getPanels = function(){ return this.getElementChildren(this.element);};Spry.Widget.Accordion.prototype.getCurrentPanel = function(){ return this.currentPanel;};Spry.Widget.Accordion.prototype.getCurrentPanelIndex = function(){ var panels = this.getPanels(); for( var i = 0 ; i < panels.length; i++ ) { if( this.currentPanel == panels[i] ) return i; } return 0;};Spry.Widget.Accordion.prototype.getPanelTab = function(panel){ if (!panel) return null; return this.getElementChildren(panel)[0];};Spry.Widget.Accordion.prototype.getPanelContent = function(panel){ if (!panel) return null; return this.getElementChildren(panel)[1];};Spry.Widget.Accordion.prototype.getElementChildren = function(element){ var children = []; var child = element.firstChild; while (child) { if (child.nodeType == 1 /* Node.ELEMENT_NODE */) children.push(child); child = child.nextSibling; } return children;};Spry.Widget.Accordion.prototype.focus = function(){ if (this.element && this.element.focus) this.element.focus();};/////////////////////////////////////////////////////Spry.Widget.Accordion.PanelAnimator = function(accordion, panel, opts){ this.timer = null; this.interval = 0; this.stepCount = 0; this.fps = 0; this.steps = 10; this.duration = 500; this.onComplete = null; this.panel = panel; this.panelToOpen = accordion.getElement(panel); this.panelData = []; Spry.Widget.Accordion.setOptions(this, opts, true); // If caller specified speed in terms of frames per second, // convert them into steps. if (this.fps > 0) { this.interval = Math.floor(1000 / this.fps); this.steps = parseInt((this.duration + (this.interval - 1)) / this.interval); } else if (this.steps > 0) this.interval = this.duration / this.steps; // Set up the array of panels we want to animate. var panels = accordion.getPanels(); for (var i = 0; i < panels.length; i++) { var p = panels[i]; var c = accordion.getPanelContent(p); if (c) { var h = c.offsetHeight; if (h == undefined) h = 0; if (p == panel || h > 0) { var obj = new Object; obj.panel = p; obj.content = c; obj.fromHeight = h; obj.toHeight = (p == panel) ? (accordion.useFixedPanelHeights ? accordion.fixedPanelHeight : c.scrollHeight) : 0; obj.increment = (obj.toHeight - obj.fromHeight) / this.steps; obj.overflow = c.style.overflow; this.panelData.push(obj); c.style.overflow = "hidden"; c.style.height = h + "px"; } } }};Spry.Widget.Accordion.PanelAnimator.prototype.start = function(){ var self = this; this.timer = setTimeout(function() { self.stepAnimation(); }, this.interval);};Spry.Widget.Accordion.PanelAnimator.prototype.stop = function(){ if (this.timer) { clearTimeout(this.timer); // If we're killing the timer, restore the overflow // properties on the panels we were animating! if (this.stepCount < this.steps) { for (i = 0; i < this.panelData.length; i++) { obj = this.panelData[i]; obj.content.style.overflow = obj.overflow; } } } this.timer = null;};Spry.Widget.Accordion.PanelAnimator.prototype.stepAnimation = function(){ ++this.stepCount; this.animate(); if (this.stepCount < this.steps) this.start(); else if (this.onComplete) this.onComplete();};Spry.Widget.Accordion.PanelAnimator.prototype.animate = function(){ var i, obj; if (this.stepCount >= this.steps) { for (i = 0; i < this.panelData.length; i++) { obj = this.panelData[i]; if (obj.panel != this.panel) obj.content.style.height = "0px"; obj.content.style.overflow = obj.overflow; obj.content.style.height = obj.toHeight + "px"; } } else { for (i = 0; i < this.panelData.length; i++) { obj = this.panelData[i]; obj.fromHeight += obj.increment; obj.content.style.height = obj.fromHeight + "px"; } }};
圖片資源: