📄 accordionbehavior.js
字号:
for (var i = 0; i < this._panes.length; i++) {
var animation = this._panes[i].animation;
if (animation) {
// Stop the animation if it was still playing
if (animation.get_isPlaying()) {
animation.stop();
}
// Remove the event handler that runs after the animation completes
if (animation._ended) {
animation.remove_ended(animation._ended);
animation._ended = null;
}
// Dispose the animation's resources (timer, etc.)
animation.dispose();
// Wipe expando properties to prevent leaks in IE6
animation._length = null;
animation._fade = null;
animation._pane = null;
animation._opening = null;
animation._behavior = null;
this._panes[i].animation = null;
}
}
},
_resizeSelectedPane : function() {
/// <summary>
/// Adjust the size of the currently selected pane (upon initialization,
/// resizing the window, etc.)
/// </summary>
/// <returns />
var pane = this.get_Pane();
if (!pane) {
return;
}
// Cache the header size so it only gets looked up when the window resizes
this._headersSize = this._getHeadersSize().height;
var original = pane.content._original;
switch (this._autoSize) {
case AjaxControlToolkit.AutoSize.None :
original.style.height = 'auto';
original.style.maxHeight = '';
break;
case AjaxControlToolkit.AutoSize.Limit :
var remaining = this._getRemainingHeight(false);
original.style.height = 'auto';
original.style.maxHeight = remaining + 'px';
break;
case AjaxControlToolkit.AutoSize.Fill :
var remaining = this._getRemainingHeight(true);
original.style.height = remaining + 'px';
original.style.maxHeight = '';
break;
}
},
_onHeaderClick : function(evt) {
/// <summary>
/// OnClick handler to open the desired pane
/// </summary>
/// <param name="evt" type="Sys.UI.DomEvent" mayBeNull="false">Event info</param>
/// <returns />
// Get the header that raised the event (by walking up the event target's
// control hierarchy until we find an element just below the root of the accordion)
var header = evt.target;
var accordion = this.get_element();
while (header && (header.parentNode !== accordion)) {
header = header.parentNode;
}
// Stop the event from bubbling out of the header pane and prevent any
// action from happening unless we clicked a control inside the header
evt.stopPropagation();
if (this._suppressHeaderPostbacks) {
evt.preventDefault();
}
// Select this pane (which saves it to ClientState and initiates an animation
// to show the content pane). If the user clicked the currently open pane and
// we're not required to keep one pane open, then we'll set the selected index
// to -1 which will close it (which means all panes will be collapsed).
var index = header._index;
if ((index === this._selectedIndex) && !this._requireOpenedPane) {
index = -1;
}
this._changeSelectedIndex(index, true);
},
_changeSelectedIndex : function(index, animate, force) {
/// <summary>
/// Change the accordion's selected pane to a new index (and optionally show the change).
/// </summary>
/// <param name="index" type="Number" integer="true" mayBeNull="false">
/// Index of the new selected pane
/// </param>
/// <param name="animate" type="Boolean" mayBeNull="false">
/// Whether or not to show the pane change (this is primarily intended to support
/// restoring _selectedIndex in initialize before any panes have been added)
/// </param>
/// <param name="force" type="Boolean" mayBeNull="true" optional="true">
/// We perform no action (i.e. raising events, animating, etc.) if the two indices represent
/// the same pane (including the case when we have two different "no pane selected values"
/// like -1 and -500). The force flag is used during initialization to skip this check since
/// we aren't able to determine invalid values yet.
/// </param>
/// <returns />
// Don't bother doing anything if the index didn't change (we actually check the
// panes so any invalid indices will match because get_Pane() will return null for
// both of them)
var lastIndex = this._selectedIndex;
var currentPane=this.get_Pane(index);
var lastPane=this.get_Pane(lastIndex);
if (!force && (currentPane == lastPane)) {
return;
}
// Raise the selectedIndexChanging event but don't change the selected index
// if the handler set the cancel property to true
var eventArgs = new AjaxControlToolkit.AccordionSelectedIndexChangeEventArgs(lastIndex, index);
this.raiseSelectedIndexChanging(eventArgs);
if (eventArgs.get_cancel()) {
return;
}
//This sets the header CSS class to the non-selected case.
if(lastPane)
{
lastPane.header.className = this._headerCssClass;
}
//This sets the selected header CSS class if available.
if(currentPane)
{
currentPane.header.className = (this._headerSelectedCssClass == '') ?
this._headerCssClass : this._headerSelectedCssClass;
}
this._selectedIndex = index;
// Save the selected pane to preserve on postbacks
this.set_ClientState(this._selectedIndex);
// Animate the pane changes if required
if (animate) {
this._changePanes(lastIndex);
}
// Raise the selectedIndexChanged event and the propertyChanged event. We include
// both events because many users have expressed that the propertyChanged event is
// not discoverable.
this.raiseSelectedIndexChanged(new AjaxControlToolkit.AccordionSelectedIndexChangeEventArgs(lastIndex, index));
this.raisePropertyChanged('SelectedIndex');
},
_changePanes : function(lastIndex) {
/// <summary>
/// The _changePanes function is used to animate the change between two panes when
/// the selected index changes. We will loop through each pane and get its
/// animation (or demand create it if it doesn't have one yet), stop playing it if
/// it's currently playing, change its parameters to either open or close, and then
/// animate it. Because we have an animation for each pane and we stop them if they
/// were already playing, the Accordion has the ability to nicely change panes
/// again before the animation is finished.
/// </summary>
/// <param name="lastIndex" type="Number" integer="true" mayBeNull="false">
/// Index of the last selected Accordion pane
/// </param>
/// <returns />
if (!this.get_isInitialized()) {
return;
}
var open = null;
var close = null;
for (var i = 0; i < this._panes.length; i++) {
// Get the animation for each pane (creating it on demand if it doesn't
// already exist)
var pane = this._panes[i];
var animation = this._getAnimation(pane);
// Stop any animations that are still playing (i.e. that haven't finished
// opening or closing from changing previous panes)
if (animation.get_isPlaying()) {
animation.stop();
}
// If we're not opening or closing the current pane, then restart the loop.
// We set the _opening flag so we don't have to keep checking if we're opening
// or closing. If opening, we also set the display style of the pane's content
// so it will be visible for the animation
if (i == this._selectedIndex) {
animation._opening = true;
open = animation;
} else if (i == lastIndex) {
animation._opening = false;
close = animation;
} else {
continue;
}
// Get the pane ready to be animated by setting
this._startPaneChange(pane, animation._opening);
// Setup the fade effect if we are using it
if (this._fadeTransitions) {
animation._fade.set_effect(animation._opening ? AjaxControlToolkit.Animation.FadeEffect.FadeIn : AjaxControlToolkit.Animation.FadeEffect.FadeOut );
}
// Set the length animation to either open or close depending on whether or
// not this is the selected pane. We also change the target to be the wrapper
// or the original pane depending on whether the AutoSize mode is set to Fill
// (because we need the background color, etc., to grow with the animation
// which means changing the size of the original, not the wrapper, should grow).
// We would prefer to animate the wrapper because it can collapse all the way to
// 0px while the original can only collapse it's content size to 0px (leaving any
// padding, margins, borders, etc.) which is why we need to factor in the size of
// the original div's gutter pixels. Animating the original content will also
// cause the animation to jump slightly at the end when it collapses smoothly down
// to the gutter pixels but then sets display: none and disappears.
if (this._autoSize === AjaxControlToolkit.AutoSize.Fill) {
animation.set_target(pane.content._original);
animation._length.set_startValue($common.getContentSize(pane.content._original).height);
animation._length.set_endValue(animation._opening ? this._getRemainingHeight(true) : 0);
} else {
animation.set_target(pane.content);
animation._length.set_startValue(pane.content.offsetHeight);
animation._length.set_endValue(animation._opening ? this._getRemainingHeight(false) : 0);
}
}
// Play the animations to open the selected pane/close any other panes. Note that we
// pulled playing the animations out of the loop so that we could always play the
// closing animation first. If you play the opening animation first, in some cases the
// accordion will always grow slightly larger (shifting the rest of the page down) and
// then shrink again because the animations are running on different timers (and
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -