📄 zptabs-accordion.js
字号:
// $Id: zptabs-accordion.js 7376 2007-06-08 11:59:17Z vkulov $
/**
* @fileoverview Accordion style tabs extension. Extends Tabs class (zptabs.js)
* adding accordion style tabs.
*
* <pre>
* Copyright (c) 2004-2006 by Zapatec, Inc.
* http://www.zapatec.com
* 1700 MLK Way, Berkeley, California,
* 94709, U.S.A.
* All rights reserved.
* </pre>
*/
/**
* Zapatec.AccordionTab constructor. Creates a new accordion tab object with
* given parameters. Configuration options are the same as in Zapatec.Tab
*
* @constructor
* @extends Zapatec.Widget
* @param {object} objArgs Tab configuration
*/
Zapatec.AccordionTab = function(objArgs) {
if (arguments.length == 0) {
objArgs = {};
}
// Call constructor of superclass
Zapatec.AccordionTab.SUPERconstructor.call(this, objArgs);
};
/**
* Unique static id of the widget class. Gives ability for Zapatec#inherit to
* determine and store path to this file correctly when it is included using
* Zapatec#include. When this file is included using Zapatec#include or path
* to this file is gotten using Zapatec#getPath, this value must be specified
* as script id.
* @private
*/
Zapatec.AccordionTab.id = 'Zapatec.AccordionTab';
// Inherit Tab
Zapatec.inherit(Zapatec.AccordionTab, Zapatec.Tab);
/**
* Creates elements needed for the new tab
*/
Zapatec.AccordionTab.prototype.createTab = function()
{
this.config.closable = false;
var tabParent = this.config.tabParent;
// Create a container for this tab
this.tabContainer = document.createElement('div');
// Add tab container to tabs
tabParent.appendChild(this.tabContainer);
this.config.tabParent = this.tabContainer;
// Call parent init
Zapatec.AccordionTab.SUPERclass.createTab.call(this);
// Show content pane
this.container.getContainer().style.display = 'block';
this.container.getContainer().style.width = '';
this.tabContainer.tabId = this.id;
// Keyboard navigation support
this.linkNode.tabIndex = Zapatec.AccordionTab.tabIndex;
if (this.config.collapseOnClick) {
// Reset onfocus handler in this mode
this.linkNode.onfocus = null;
}
if (!this.tab2tab)
{
// Next tabIndex is reserved for tab content
Zapatec.AccordionTab.tabIndex += 2;
}
// Add title bar to tab
this.chooser = Zapatec.Utils.createElement('div');
this.chooser.className = 'tabChooser';
this.chooser.onclick = this.onActivate;
this.tabContainer.insertBefore(this.chooser,
this.tabContainer.childNodes[0]);
this.chooser.appendChild(this.linkNode);
if (this.config.tabType != "iframe") {
// Create WCH
this.wch = Zapatec.Utils.createWCH(this.container.getContainer());
// Put WCH under container
if (this.wch) {
this.wch.style.zIndex = -1;
}
}
};
/**
* Configures the widget. Gets called from init and reconfigure methods of
* superclass.
*
* @private
* @param {object} objArgs User configuration
*/
Zapatec.AccordionTab.prototype.configure = function(objArgs) {
// Define config options
// Id of the tab
this.defineConfigOption('collapseOnClick', null);
this.defineConfigOption('visibleHeight', -1);
// Call parent method
Zapatec.AccordionTab.SUPERclass.configure.call(this, objArgs);
if (this.config.content && 1 == this.config.content.nodeType) {
// Get tab height as specified in html
this.config.visibleHeight = parseInt(this.config.content.style.height);
this.config.content.style.height = "";
}
}
/**
* Determines child node of the container which gets focus first.
* Needed for keyboard navigation.
* @private
*/
Zapatec.AccordionTab.prototype.getFocusOn = function ()
{
// Remove old value
this.focusOn = null;
// Check keyboard navigation type
if (this.tab2tab)
{
return;
}
// Put it in separate process to speed up initialization
var self = this;
setTimeout(function()
{
// Flag to determine lower tabIndex
var iTabIndex = 0;
// Gets element with lower tabIndex
function parse(objNode)
{
var objChild = objNode.firstChild;
while (objChild)
{
if (objChild.nodeType == 1)
{
// ELEMENT_NODE
var strTag = objChild.tagName.toLowerCase();
if (strTag == 'a' || strTag == 'input' || strTag == 'select' ||
strTag == 'textarea' || strTag == 'button') // Element may obtain focus
{
if (!self.focusOn)
{
self.focusOn = objChild;
}
else if (objChild.tabIndex && objChild.tabIndex > 0 &&
(!iTabIndex || iTabIndex > objChild.tabIndex))
{
self.focusOn = objChild;
iTabIndex = objChild.tabIndex;
}
if (!objChild.tabIndex)
{
objChild.tabIndex = self.linkNode.tabIndex + 1;
}
}
parse(objChild);
}
objChild = objChild.nextSibling;
}
};
// Parse tab content
parse(self.container.getContainer());
}, 0);
};
/**
* Zapatec.AccordionTabs constructor. Creates a new accordion tabs object
* with given parameters.
*
* @constructor
* @extends Zapatec.Widget
* @param {object} objArgs Tab configuration
*
* See Zapatec.Tabs for a list of recognized properties of the config object
*/
Zapatec.AccordionTabs = function(objArgs) {
Zapatec.AccordionTabs.SUPERconstructor.call(this, objArgs);
};
/**
* Unique static id of the widget class. Gives ability for Zapatec#inherit to
* determine and store path to this file correctly when it is included using
* Zapatec#include. When this file is included using Zapatec#include or path
* to this file is gotten using Zapatec#getPath, this value must be specified
* as script id.
* @private
*/
Zapatec.AccordionTabs.id = 'Zapatec.AccordionTabs';
// Inherit Tabs
Zapatec.inherit(Zapatec.AccordionTabs, Zapatec.Tabs);
/**
* Configures the widget. Gets called from init and reconfigure methods of
* superclass.
*
* @private
* @param {object} objArgs User configuration
*/
Zapatec.AccordionTabs.prototype.configure = function(objArgs) {
// Define config options
// If tabs are to collapse on click when they are active
this.defineConfigOption('collapseOnClick', false);
// If page is to scroll with tabs as they slide.
// This option is true by default for IE6 and Mozilla
this.defineConfigOption('scrollPageOnSlide',
(Zapatec.is_ie && !Zapatec.is_ie7) || Zapatec.is_gecko);
// Call parent method
Zapatec.AccordionTabs.SUPERclass.configure.call(this, objArgs);
}
/**
* Initializes object.
*
* @param {object} objArgs User configuration
*/
Zapatec.AccordionTabs.prototype.init = function(objArgs, i)
{
// Reference to this
var self = this;
// Patch onInit handler
var funcOnInit = objArgs.onInit;
objArgs.onInit = function()
{
// Setup tabs
//var _tabContainer = Zapatec.Widget.getElementById(self.config.tabs);
var _tabContainer = self.config.tabs;
var items = _tabContainer.childNodes;
for (var i = items.length - 1; i >= 0; i--)
{
var tagName = items[i].tagName;
if (tagName) {
tagName = tagName.toLowerCase();
}
if ('div' == tagName || 'iframe' == tagName) {
self.config._tabArray.push(items[i]);
}
}
topPos = self.config._tabArray[self.config._tabArray.length - 1].offsetTop;
// Position tabs
// You need the number of tabs and their order
// then, you can calculate where they should start and stop.
////
// Each tab has a visible area of:
// tabContainerHeight - (numOfTabs-1 * heightOfTabTitle)
//
// Each tab has a unique viewing position, derived from its place among the tabs as follows:
// tabTop = tabContainerTop + (tabIndex-1 * heightOfTabTitle)
//
// Each tab has a unique hidden position, derived from its place among the tabs as follows:
// tabTop = tabContainerTop + tabContainerHeight - (tabIndex * heightOfTabTitle)
//
// The tabs are layerd on top of each other in the order in which they appear in the HTML.
// The first tab appears as the default.
// In opening a tab, the chosen tab will carry all tabs below it along with it.
// In closing a tab, the chosen tab will carry all tabs above it along with it.
var _tabZIndex = 100;
for (var i = 0; i < self.config._tabArray.length; i++)
{
var tab = self.getTabByIndex(i);
var tabContainer = tab.tabContainer;
var contentContainer = tab.container.getContainer();
var visibleHeight = tab.config.visibleHeight;
if (tab.config.tabType.toLowerCase() == "iframe") {
tab.container.getContainer().style.width = '100%';
}
// Set tab content container height to 1 pixel
contentContainer.style.height = '1px';
Zapatec.Utils.addClass(contentContainer, "zpTabsNoOverflow");
// Subract two to account for border
tabContainer.style.width = _tabContainer.style.width;
// Layer the tabs
tabContainer.style.zIndex = _tabZIndex--;
// This tab's array position
tabContainer.arrayPosition = i;
// This tab's viewing position
tabContainer.viewingPosition = topPos + ((self.config._tabArray.length - 1 - i) * self.config.tabBarHeight);
// This tab's hidden position
tabContainer.hiddenPosition = topPos + parseInt(_tabContainer.style.height) - ((i + 1) * self.config.tabBarHeight);
// This tab's final viewing height
if (visibleHeight && 0 < visibleHeight) {
tabContainer.viewingHeight = visibleHeight;
}
else {
var tabContainerHeight = parseInt(_tabContainer.style.height);
if (tabContainerHeight && 0 < tabContainerHeight) {
// Calculate tab visible height by tabContainer total height and tab count
tabContainer.viewingHeight = tabContainerHeight -
((self.config._tabArray.length/*-1*/) * self.config.tabBarHeight);
}
else {
// Use default height if one can't be computed
tabContainer.viewingHeight = 100;
}
}
// This tab's hidden height
tabContainer.hiddenHeight = self.config.tabBarHeight;
}
// Get tab id to make active
var activeTabId = self.getInitialActiveTabId();
if (-1 != activeTabId) {
// Get tab to make active
var activeTab = self.getTab(activeTabId);
var tabContainer = activeTab.tabContainer;
var contentContainer = activeTab.container.getContainer();
// Activate tab
contentContainer.style.height = tabContainer.viewingHeight + 'px';
var setOverflowFunc = function() {
Zapatec.Utils.removeClass(contentContainer, "zpTabsNoOverflow");
};
if (Zapatec.is_ie) {
setTimeout(setOverflowFunc, 0);
}
else {
setOverflowFunc();
}
self.currentIndex = activeTab.index;
// Reload tab if needed and call onTabChange
self.refreshTab(activeTab, null, activeTabId);
}
// Patch onBeforeTabChange handler
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -