⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 accordionbehavior.js

📁 AJAX 应用 实现页面的无刷新
💻 JS
📖 第 1 页 / 共 5 页
字号:
    /// even number of child divs (such that ith pane has a header at div 2i and
    /// has content at div 2i+1).
    /// </param>
    AjaxControlToolkit.AccordionBehavior.initializeBase(this, [element]);
    
    // The _selectedIndex variable is used to track the currently visible content
    // pane.  It is persisted via ClientState so that it can be restored on PostBack.
    // If 0 <= _selectedIndex < _panes.Length is not true, then no pane is selected
    // (and they all appear collapsed).  While any index outside the bounds of the
    // _panes array indicates that no pane is selected, we don't automatically set
    // the value to a sentinel like -1 (especially on the server) because it's
    // possible for additional panes to be added at any time.  We abstract this
    // problem using the get_Pane() function which returns the selected pane when
    // it's called with no arguments (and returns null when the current selected
    // index is invalid).
    this._selectedIndex = 0;
    
    // The _panes array represents the collection of Accordion panes.  Each element of
    // the array is an object of the form {header, content, animation} corresponding
    // to that pane's header section, content section, and the animation used to open
    // and close its content section.  The content element is a new div that has been
    // created to wrap the original div (so we can completely collapse it - even if it
    // has padding, margins, etc.) which is pointed to by a dynamic _original property.
    // The header element has a dynamic _index property indicating its position in the
    // Accordion's pane collection (used primarily by the headers' shared click handler).
    // Furthermore, the animation will either be an instance of LengthAnimation or
    // ParallelAnimation (in the latter case, it will have two children which are a
    // LengthAnimation and a FadeAnimation).  There will be two dynamic properties
    // _length and _fade pointing to each of these children (to easily set the length
    // and fadeEffect properties).  There is also a dynamic _ended property which is
    // an event handler to be fired when the animation is complete, a dynamic _opening
    // property to indicate whether the animation was opening or closing the pane, and
    // a dynamic _pane property to provide a reference to the pane that was being
    // animated.
    this._panes = [];
    
    // The this._fadeTransitions flag determines whether or not we enable a simple fade
    // animation effect on top of the opening and closing effect
    this._fadeTransitions = false;
    
    // The this._duration represents the transition duration of the animations in seconds
    this._duration = 0.25;
    
    // framesPerSecond is used to tune the animation to perform well depending on
    // the the type of effect being used an the number of accordion panes, etc.
    this._framesPerSecond = 30;
    
    // Determine how growth of the Accordion will be controlled.  If it is set to
    // None, then the Accordion can grow as large or as small as necessary.  If it is
    // set to Limit, then the Accordion will always be less than or equal to its
    // available space.  If it is set to Fill, then it will always be equal to its
    // available space.
    this._autoSize = AjaxControlToolkit.AutoSize.None;
    
    // Whether or not clicking the header will close the currently opened pane (which
    // leaves all the Accordion's panes closed)
    this._requireOpenedPane = true;
    
    // Whether or not we suppress the client-side click handlers of any elements
    // (including server controls like Button or HTML elements like anchor) in the header
    // sections of the Accordion
    this._suppressHeaderPostbacks = false;
    
    // Size of all the headers
    this._headersSize = 0;

    // The _headerClickHandler is a reference to the event handler that all the header
    // elements of our panes will be wired up to
    this._headerClickHandler = null;
    
    // The _headerSelectedCssClass is the css class applied to the selected header.    
    this._headerCssClass = '';
    
    // The _headerSelectedCssClass is the css class applied to the selected header.    
    this._headerSelectedCssClass = '';
    
    // The _headerSelectedCssClass is the css class applied to the selected header.    
    this._contentCssClass = '';
        
    // The _resizeHandler is a reference to the global event handler used to patch
    // up the accordion when the window is resized
    this._resizeHandler = null;
}
AjaxControlToolkit.AccordionBehavior.prototype = {
    initialize : function() {
        /// <summary>
        /// The initialize function is responsible for getting the selected index from
        /// the ClientState mechanism and walking the children of the behavior's target
        /// to find all of the accordion's child panes.  It builds up a collection of the
        /// panes from the headers and content sections.  Then we hide all the content
        /// sections that aren't selected and initialize the layout.
        /// </summary>
        /// <returns />
        AjaxControlToolkit.AccordionBehavior.callBaseMethod(this, 'initialize');
        
        // Create the onclick handler used by the accordion's headers
        this._headerClickHandler = Function.createDelegate(this, this._onHeaderClick);
        
        // Get the selected index from ClientState
        var state = this.get_ClientState();
        if (state !== null && state !== '') {
            this._changeSelectedIndex(parseInt(state), false, true);
        }
        
        // Walk the children of the target control to obtain the accordion's child panes.
        // We are expecting a hierarchy of divs that looks like:
        //   <div id="accordion">         this.element
        //     ...
        //     <div id="header_i"></div>   this.element.childNodes[2i]
        //     <div id="content_i"></div>  this.element.childNodes[2i+1]
        //     ...
        //   </div>
        // We'll turn this hierarchy of divs into objects filling the _panes collection.
        // See the comment above the _panes array for more details on the structure of
        // these objects.  It's also worth pointing out that we effectively "box" the
        // index so it can be passed by reference to the _getNextDiv function
        var nodes = this.get_element().childNodes;
        var index = { };
        for (index.value = 0; index.value < nodes.length; index.value++) {
            var header = this._getNextDiv(nodes, index);
            if (!header) {
                break;
            }
            var content = this._getNextDiv(nodes, index);
            if (content) {
                // Add the pane once we've found both a header and a content section
                // (but bump the loop index back so we don't skip an element when the
                // loop increments)
                this.addPane(header, content);
                index.value--;
            }
        }
        
        // Ensure we have an opened pane if we're required to (and use the first
        // pane if we don't have a valid selected index)
        if (this._requireOpenedPane && !this.get_Pane() && this._panes.length > 0) {
            this._changeSelectedIndex(0, false, true);
        }
        
        // Setup the layout for the given AutoSize mode
        this._initializeLayout();
    },
    
    _getNextDiv : function(nodes, index) {
        /// <summary>
        /// Get the next div in a sequence of child nodes starting at the
        /// given index
        /// </summary>
        /// <param name="nodes" type="Array" mayBeNull="false" elementMayBeNull="true"
        ///   elementType="Sys.UI.DomElement" elementDomElement="true">
        /// Array of child nodes (i.e. element.childNodes)
        /// </param>
        /// <param name="index" type="Object" mayBeNull="false">
        /// The index is an object of the form { value } where index.value represents
        /// the current index in the collection of nodes.  We wrap the index in an object
        /// to perform the .NET equivalent of boxing so it can be passed by reference.
        /// </param>
        /// <returns type="Sys.UI.DomElement" DomElement="true" mayBeNull="true">
        /// The next DOM element representing a div tag, starting at the provided index.
        /// </returns>
        
        var div = null;
        while (index.value < nodes.length && (div = nodes[index.value++])) {
            if (div.tagName && (div.tagName.toLowerCase() === 'div')) {
                break;
            }
        }
        return div;
    },
    
    addPane : function(header, content) {
        /// <summary>
        /// Create a new Accordion pane given references to its header and content divs
        /// and add it to the _panes collection.  We also wrap the content div in a new
        /// container div, add a click handler to the header div, etc.
        /// </summary>
        /// <param name="header" type="Sys.UI.DomElement" domElement="true" mayBeNull="false">
        /// Header element of the new Accordion pane
        /// </param>
        /// <param name="content" type="Sys.UI.DomElement" domElement="true" mayBeNull="false">
        /// Content element of the new Accordion pane
        /// </param>
        /// <returns type="Object" mayBeNull="false">
        /// New pane object added to the end of the Accordion's pane collection.  The pane
        /// is an object of the form {header, content, animation} corresponding to that
        /// pane's header section, content section, and the animation used to open and
        /// close its content section.  The content element is a new div that has been
        /// created to wrap the original div (so we can completely collapse it - even if it
        /// has padding, margins, etc.) which is pointed to by a dynamic _original property.
        /// The header element has a dynamic _index property indicating its position in the
        /// Accordion's pane collection (used primarily by the headers' shared click handler).
        /// Furthermore, the animation will either be an instance of LengthAnimation or
        /// ParallelAnimation (in the latter case, it will have two children which are a
        /// LengthAnimation and a FadeAnimation).  There will be two dynamic properties
        /// _length and _fade pointing to each of these children (to easily set the length
        /// and fadeEffect properties).  There is also a dynamic _ended property which is
        /// an event handler to be fired when the animation is complete, a dynamic _opening
        /// property to indicate whether the animation was opening or closing the pane, and
        /// a dynamic _pane property to provide a reference to the pane that was being
        /// animated.
        /// </returns>
    
        // Create the new pane object
        var pane = { };
        pane.animation = null;
        
        // Initialize the header
        pane.header = header;
        header._index = this._panes.length;
        $addHandler(header, "click", this._headerClickHandler);
        
        // Wrap the content in a new element
        var accordion = this.get_element();
        var wrapper = document.createElement('div');
        accordion.insertBefore(wrapper, content);
        wrapper.appendChild(content);
        wrapper._original = content;
        pane.content = wrapper;
    
        // Remove any style facets (possibly) automatically applied by
        // CSS selectors so they don't interfere with UI/layout
        wrapper.style.border = '';
        wrapper.style.margin = '';
        wrapper.style.padding = '';

        // Add the new pane at the bottom of the accordion
        Array.add(this._panes, pane);
        
        // Setup the layout attributes for the pane so that it will be in a proper opened or
        // closed state (we don't bother setting the opacity of the wrapper with
        // $common.setElementOpacity(wrapper, selected ? 1 : 0); because it will
        // be taken care of by the animation)
        this._initializePane(header._index);
        
        // Since the content section of the accordion panes will be sent down from the server
        // with display: none (so the content sections aren't shown before they're wrapped in
        // new divs) we'll turn them back on once they've been wrapped in hidden divs
        content.style.display = 'block';
        
        return pane;
    },
    
    _getAnimation : function(pane) {
        /// <summary>
        /// Get the animation for the specified accordion section or demand create
        /// the animation if it doesn't already exist.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -