JQuery UI选项卡:嵌套选项卡,AJAX加载和后退按钮

时间:2012-12-12 07:19:43

标签: jquery-ui-tabs back-button

我正在使用AJAX加载JQuery UI标签。

我有3个级别的嵌套UI标签:

  1. 垂直
  2. 水平
  3. 水平
  4. 大多数东西只有2级深,但有些是3级。问题是第3级。我跟着这个:

    http://benalman.com/code/projects/jquery-bbq/examples/fragment-jquery-ui-tabs/

    但它不包括标签的嵌套。

    页面布局如下:

    <script type="text/javascript">
        var tabs;
        var tab_a_selector;
        var tab_a_vertical_selector;
    
        $(function() {              
    
            $("#menuTabs").tabs({
                ajaxOptions: {
                    cache: false
                }
            }).addClass("ui-tabs-vertical ui-helper-clearfix"); 
            $("#menuTabs li").removeClass('ui-corner-top').addClass('ui-corner-left');
            $(".ui-tabs-vertical .ui-tabs-nav").removeClass("ui-tabs-nav").addClass("ui-tabs-nav-vert")
    
            $("#menuItem0").tabs();
            $("#menuItem1").tabs(); 
            //...
    
            /* -- enables Back button for nested tabs -- */
    
            // The "tab widgets" to handle.
            tabs = $('.tabs');
    
            // This selector will be reused when selecting actual tab widget A elements.
            tab_a_selector = 'ul.ui-tabs-nav a';
            tab_a_vertical_selector = 'ul.ui-tabs-nav-vert a';
            // Enable tabs on all tab widgets. The `event` property must be overridden so
            // that the tabs aren't changed on click, and any custom event name can be
            // specified. Note that if you define a callback for the 'select' event, it
            // will be executed for the selected tab whenever the hash changes.
            tabs.tabs({ event: 'change' });
    
            // Define our own click handler for the tabs, overriding the default.
            tabs.find(tab_a_selector).click(function(){
                var state = {};
    
                // Get the id of this tab widget.
                id = $(this).closest( '.tabs' ).attr( 'id' );
    
                // Get the index of this tab.
                idx = $(this).parent().prevAll().length;
    
                // Set the new state
                // This is done as below to remove any state from deeper levels of nested tabs.
                state ['menuTabs'] = $.bbq.getState('menuTabs');
                state[ id ] = idx;                  
                $.bbq.pushState( state, 2 );
            });
            tabs.find(tab_a_vertical_selector).click(function(){                
                var state = {};
    
                // Get the id of this tab widget.
                id = $(this).closest( '.tabs' ).attr( 'id' );
    
                // Get the index of this tab.
                idx = $(this).parent().prevAll().length;
    
                // Set the state!
                state[ id ] = idx;  
    
                // 2 -> replaces old state with new state. meaning indexes of nested tabs are removed
                $.bbq.pushState( state, 2 ); 
            });
    
            // Bind an event to window.onhashchange that, when the history state changes,
            // iterates over all tab widgets, changing the current tab as necessary.
            $(window).bind( 'hashchange', function(e) {             
    
                // Iterate over all tab widgets.
                tabs.each(function(){
    
                    // Get the index for this tab widget from the hash, based on the
                    // appropriate id property. In jQuery 1.4, you should use e.getState()
                    // instead of $.bbq.getState(). The second, 'true' argument coerces the
                    // string value to a number.
                    var idx = $.bbq.getState( this.id, true ) || 0;
    
                    // Select the appropriate tab for this tab widget by triggering the custom
                    // event specified in the .tabs() init above (you could keep track of what
                    // tab each widget is on using .data, and only select a tab if it has
                    // changed).
                    $(this).find( tab_a_selector).eq( idx ).triggerHandler( 'change' );
                    $(this).find( tab_a_vertical_selector ).eq( idx ).triggerHandler( 'change' );
                });                 
            })
    
            // Since the event is only triggered when the hash changes, we need to trigger
            // the event now, to handle the hash the page may have loaded with.
            $(window).trigger( 'hashchange' );
    
            /* -- END enables Back button for nested tabs -- */
        });
    </script>
    
    <div id="menuTabs" class="tabs">
        <ul>
            <li><a href="#menuItem0">menuItem0</a></li>
            <li><a href="#menuItem1">menuItem1</a></li>
            <li><a href="#menuItem2">menuItem2</a></li>
        </ul>
    
        <div id="menuItem0" class="tabs">
            <ul>
                <li><a href="content/menuItem0/Intro.html">Intro</a></li>
            </ul>                       
        </div>
        <div id="menuItem1" class="tabs">
            <ul>
                <li><a href="content/menuItem1/Intro.html">Introduction</a></li>
                <li><a href="content/menuItem1/Guide.html">Guide</a></li>
                <li><a href="content/menuItem1/abc.html">abc</a></li>                       
            </ul>                       
        </div>
        <!--...-->
    </div>
    

    第3级标签位于上述html页面中,例如abc.html:

    <script type="text/javascript"> 
    
        var rNumberTabs = $("#rNumber").tabs(); 
        rNumberTabs.tabs({ event: 'change' });
        rNumberTabs.find(tab_a_selector).click(function(){
            var state = {};
    
            // Get the id of this tab widget.
            id = $(this).closest( '.tabs' ).attr( 'id' );
    
            // Get the index of this tab.
            idx = $(this).parent().prevAll().length;
    
            // Set the state!
            state[ id ] = idx;                  
            $.bbq.pushState( state );
        });
        tabs = tabs.add(grNumberTabs);
        // If this is triggered it leads to an infinte loop,
        // if not, I can't even browse to any other tab than the first
        // one on he third level, eg. it automatically jumps back
        // to first one.
        $(window).trigger( 'hashchange' );
    </script>
    <div id="rNumber" class="tabs">
        <ul>
            <li><a href="#layout">Layout</a></li>       
            <li><a href="#prefix">Prefix</a></li>
        </ul>
        <div id="layout">
            <!-- Content here -->
        </div>
        <div id="prefix">
            <!-- Content here -->
        </div>
    </div>
    

    我能解决的任何想法?

1 个答案:

答案 0 :(得分:0)

所以这是我目前的解决方案。无限循环的问题似乎是由于当使用AJAX加载选项卡时,每次点击都会再次加载选项卡。由于包含第3级选项卡的选项卡也包含JavaScript(请参阅问题),因此重新加载此选项卡会导致问题。

解决方案是缓存标签:

$("#menuTabs").tabs({
    cache: true,
    ajaxOptions: {
        cache: false
    }
})

注意:您必须将Ajax缓存设置为false:

http://docs.jquery.com/UI/Tabs#option-cache

第3级标签相同。这里还删除了对hashchange事件的调用。

var rNumberTabs = $("#rNumber").tabs({
    cache: true,
    ajaxOptions: {
        cache: false
    }
});
//snipped..
//$(window).trigger( 'hashchange' ); remove this line