sync.tabpane.js
来自「echo3 很炫的ajax框架技术 js 演示demo ajax j2ee 里」· JavaScript 代码 · 共 1,019 行 · 第 1/3 页
JS
1,019 行
/**
* Component rendering peer: TabPane
*/
Extras.Sync.TabPane = Core.extend(Echo.Render.ComponentSync, {
$static: {
_supportedPartialProperties: ["activeTab", "activeTabIndex"],
_paneInsets: 0,
_defaultBorderType: Extras.TabPane.BORDER_TYPE_ADJACENT_TO_TABS,
_defaultForeground: "#000000",
_defaultInsets: 2,
_defaultTabActiveBorder: "1px solid #00004f",
_defaultTabActiveHeightIncrease: 2,
_defaultTabAlignment: "top",
_defaultTabCloseIconTextMargin: 5,
_defaultTabContentInsets: 0,
_defaultTabIconTextMargin: 5,
_defaultTabInactiveBorder: "1px solid #7f7f7f",
_defaultTabInset: 10,
_defaultTabInsets: "3px 8px",
_defaultTabPosition: Extras.TabPane.TAB_POSITION_TOP,
_defaultTabSpacing: 0,
/**
* Runnable to manage scrolling animation.
*/
ScrollRunnable: Core.extend(Core.Web.Scheduler.Runnable, {
repeat: true,
timeInterval: 20,
reverse: false,
distance: 0,
/** Minimum distance to move (in case of click rather than hold */
clickDistance: 50,
/** Rate to scroll when scroll button held. */
pixelsPerSecond: 400,
/** Initial scroll position. */
initialPosition: null,
disposed: false,
peer: null,
lastInvokeTime: null,
$construct: function(peer, reverse) {
this.peer = peer;
this.reverse = reverse;
this.initialPosition = peer.scrollPosition;
this.lastInvokeTime = new Date().getTime();
},
dispose: function() {
if (!this.disposed) {
Core.Web.Scheduler.remove(this);
}
this.disposed = true;
},
finish: function() {
if (this.distance < this.clickDistance) {
this.distance = this.clickDistance;
this.updatePosition();
}
this.dispose();
},
run: function() {
var time = new Date().getTime();
this.distance += Math.ceil(this.pixelsPerSecond * (time - this.lastInvokeTime) / 1000);
this.lastInvokeTime = time;
this.updatePosition();
},
updatePosition: function() {
var position = this.initialPosition + ((this.reverse ? -1 : 1) * this.distance);
if (!this.peer.setScrollPosition(position)) {
this.dispose();
}
}
})
},
$load: function() {
Echo.Render.registerPeer("Extras.TabPane", this);
},
_icons: null,
/**
* Primary DIV element.
* @type Element
*/
_div: null,
/**
* DIV element which contains content. All child components are rendered within this DIV,
* only one is allowed to be visibly displayed at a given time.
* @type Element
*/
_contentContainerDiv: null,
/**
* Element containing tab headers.
* @type Element
*/
_headerContainer: null,
/**
* The renderId of the active tab.
* @type String
*/
_activeTabId: null,
/**
* Scroll previous arrow.
*/
_previousControlDiv: null,
/**
* Scroll next arrow.
*/
_nextControlDiv: null,
/**
* Array containing <code>Extras.Sync.TabPane.Tab</code> objects represented the displayed tabs.
* Each index of this array matches the corresponding child component index.
* @type Array
*/
_tabs: null,
/**
* Combined width of all tabs.
*/
_totalTabWidth: 0,
/**
* Flag indicating whether the header size may need to be reconfigured (by invoking configureHeaderSize() in the next
* renderDisplay() execution.
*/
_configureHeaderSizeRequired: false,
_scrollRunnable: null,
scrollPosition: 0,
$construct: function() {
this._tabs = [];
},
/**
* Adds a tab and renders it.
*
* @param {Echo.Update.ComponentUpdate} update the component update
* @param {Extras.Sync.TabPane.Tab} tab the tab to be added
* @param index the index at which the tab should be added
*/
_addTab: function(update, tab, index) {
if (index == null || index == this._tabs.length) {
this._tabs.push(tab);
tab._render(update);
this._headerTabContainerTr.appendChild(tab._headerTd);
this._contentContainerDiv.appendChild(tab._contentDiv);
} else {
this._tabs.splice(index, 0, tab);
tab._render(update);
this._headerTabContainerTr.insertBefore(tab._headerTd,
this._headerTabContainerTr.childNodes[index]);
this._contentContainerDiv.insertBefore(tab._contentDiv,
this._contentContainerDiv.childNodes[index]);
}
},
_configureHeaderSize: function() {
var height = new Core.Web.Measure.Bounds(this._headerTabContainerDiv).height;
if (height === 0) {
// Cannot calculate header size.
return;
}
this._configureHeaderSizeRequired = false;
var borderSize = Echo.Sync.Border.getPixelSize(this._tabActiveBorder);
if (this._tabPosition == Extras.TabPane.TAB_POSITION_BOTTOM) {
this._contentContainerDiv.style.top = "0";
this._contentContainerDiv.style.bottom = (height - borderSize) + "px";
} else {
this._contentContainerDiv.style.top = (height - borderSize ) + "px";
this._contentContainerDiv.style.bottom = "0";
}
this._contentContainerDiv.style.left = "0";
this._contentContainerDiv.style.right = "0";
Core.Web.VirtualPosition.redraw(this._contentContainerDiv);
Core.Web.VirtualPosition.redraw(this._headerContainerDiv);
for (var i = 0; i < this._tabs.length; ++i) {
this._tabs[i]._renderDisplay();
}
},
/**
* Determines the renderId of the active tab child component.
* This method first queries the component's <code>activeTab</code> property,
* and if it is not set, the id is determined by finding the child component at the
* index specified by the component's <code>activeTabIndex</code> property.
*
* @return the active tab renderId
* @type String
*/
_getActiveTabId: function() {
var activeTabId = this.component.get("activeTab");
if (!activeTabId) {
var activeTabIndex = this.component.get("activeTabIndex");
if (activeTabIndex != null && activeTabIndex < this.component.children.length) {
activeTabId = this.component.children[activeTabIndex].renderId;
}
}
return activeTabId;
},
/**
* Retrieves the tab instance with the specified tab id.
*
* @param tabId the tab render id
* @return the tab, or null if no tab is present with the specified id
* @type Extras.Sync.TabPane.Tab
*/
_getTabById: function(tabId) {
for (var i = 0; i < this._tabs.length; ++i) {
var tab = this._tabs[i];
if (tab._childComponent.renderId == tabId) {
return tab;
}
}
return null;
},
/**
* Handler for mouse down event on previous/next scroll buttons.
*/
_processScrollStart: function(e) {
if (!this.client || !this.client.verifyInput(this.component)) {
return;
}
this._scrollRunnable = new Extras.Sync.TabPane.ScrollRunnable(this, e.registeredTarget === this._previousControlDiv);
Core.Web.Scheduler.add(this._scrollRunnable);
},
/**
* Handler for mouse up event on previous/next scroll buttons.
*/
_processScrollStop: function(e) {
if (!this._scrollRunnable) {
return;
}
this._scrollRunnable.finish();
this._scrollRunnable = null;
},
/**
* Removes a specific tab.
*
* @param {Extras.Sync.TabPane.Tab} tab the tab to remove
*/
_removeTab: function(tab) {
var tabIndex = Core.Arrays.indexOf(this._tabs, tab);
if (tabIndex == -1) {
return;
}
if (tab._childComponent.renderId == this._activeTabId) {
this._activeTabId = null;
}
this._tabs.splice(tabIndex, 1);
Core.Web.DOM.removeNode(tab._headerTd);
Core.Web.DOM.removeNode(tab._contentDiv);
tab._dispose();
},
renderAdd: function(update, parentElement) {
this._icons = { };
// Configure Properties
this._activeTabId = this._getActiveTabId();
this._borderType = this.component.render("borderType", Extras.Sync.TabPane._defaultBorderType);
this._insets = this.component.render("insets", Extras.Sync.TabPane._defaultInsets);
this._tabActiveBorder = this.component.render("tabActiveBorder", Extras.Sync.TabPane._defaultTabActiveBorder);
this._tabActiveHeightIncreasePx = Echo.Sync.Extent.toPixels(this.component.render("tabActiveHeightIncrease",
Extras.Sync.TabPane._defaultTabActiveHeightIncrease));
this._tabInactiveBorder = this.component.render("tabInactiveBorder", Extras.Sync.TabPane._defaultTabInactiveBorder);
this._tabInsetPx = Echo.Sync.Extent.toPixels(this.component.render("tabInset",Extras.Sync.TabPane._defaultTabInset));
this._tabPosition = this.component.render("tabPosition", Extras.Sync.TabPane._defaultTabPosition);
this._tabSpacing = this.component.render("tabSpacing", Extras.Sync.TabPane._defaultTabSpacing);
this._tabCloseEnabled = this.component.render("tabCloseEnabled", false);
if (this._tabCloseEnabled) {
this._icons.defaultIcon = this.component.render("tabCloseIcon");
this._icons.disabledIcon = this.component.render("tabDisabledCloseIcon");
this._icons.rolloverIcon = this.component.render("tabRolloverCloseIcon");
}
// Render Border Insets
var pixelInsets = Echo.Sync.Insets.toPixels(this._insets);
if (this._borderType == Extras.TabPane.BORDER_TYPE_SURROUND) {
// Do nothing, pixelInsets values are correct.
} else if (this._borderType == Extras.TabPane.BORDER_TYPE_PARALLEL_TO_TABS) {
pixelInsets.left = pixelInsets.right = 0;
} else if (this._tabPosition == Extras.TabPane.TAB_POSITION_BOTTOM) {
pixelInsets.left = pixelInsets.right = pixelInsets.top = 0;
} else {
pixelInsets.left = pixelInsets.right = pixelInsets.bottom = 0;
}
// Create Main Element
this._div = document.createElement("div");
this._div.id = this.component.renderId;
this._div.style.cssText = "position:absolute;overflow:hidden;top:" + pixelInsets.top + "px;right:" + pixelInsets.right +
"px;bottom:" + pixelInsets.bottom + "px;left:" + pixelInsets.left + "px;";
// Render Header Container
this._headerContainerDiv = document.createElement("div");
this._headerContainerDiv.style.cssText = "position:absolute;overflow:hidden;z-index:1;" +
(this._tabPosition == Extras.TabPane.TAB_POSITION_BOTTOM ? "bottom" : "top") + ":0;" +
"left:" + this._tabInsetPx + "px;right:" + this._tabInsetPx + "px;";
this._headerTabContainerDiv = document.createElement("div");
this._headerTabContainerTable = document.createElement("table");
this._headerTabContainerTable.style.padding = 0;
this._headerTabContainerTable.cellPadding = 0;
this._headerTabContainerTable.cellSpacing = 0;
var tbody = document.createElement("tbody");
this._headerTabContainerTr = document.createElement("tr");
tbody.appendChild(this._headerTabContainerTr);
this._headerTabContainerTable.appendChild(tbody);
this._headerTabContainerDiv.appendChild(this._headerTabContainerTable);
this._headerContainerDiv.appendChild(this._headerTabContainerDiv);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?