WordPress.org

Make WordPress Core

Changeset 30388


Ignore:
Timestamp:
11/19/2014 06:22:15 PM (6 years ago)
Author:
iandstewart
Message:

Twenty Fifteen: Making the sidebar sticky for everyone. When we have a long sidebar, let it scroll with the content, but fixing the sidebar and no longer scrolling when we get to the end of the sidebar content. Scroll up and the sidebar starts scrolling up to, eventually staying fixed when it gets back to the top.

Props celloexpressions, avryl, fixes #30366.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-content/themes/twentyfifteen/js/functions.js

    r30324 r30388  
    77
    88( function( $ ) {
    9     var $body, $window, sidebar, toolbarOffset;
     9    var $body, $window, $document, $sidebar, adminbarOffset, top = false,
     10        bottom = false, windowWidth, windowHeight, lastWindowPos = 0,
     11        topOffset = 0, documentHeight, sidebarWidth, sidebarHeight, resizeTimer;
    1012
    1113    // Add dropdown toggle that display child menu items.
     
    3335        }
    3436
    35         // Hide button if there is no widgets and menu is missing or empty.
     37        // Hide button if there are no widgets and the menus are missing or empty.
    3638        menu    = secondary.find( '.nav-menu' );
    3739        widgets = secondary.find( '#widget-area' );
     
    4951    } )();
    5052
     53    // Sidebar scrolling.
     54    function resize() {
     55        windowWidth = $window.width();
     56        windowHeight = $window.height();
     57        documentHeight = $document.height();
     58        sidebarHeight = $sidebar.height();
    5159
    52     // Sidebar (un)fixing: fix when short, un-fix when scroll needed
    53     function fixedOrScrolledSidebar() {
    54         if ( $window.width() >= 955 ) {
    55             if ( sidebar.scrollHeight < ( $window.height() - toolbarOffset ) ) {
    56                 $body.addClass( 'sidebar-fixed' );
    57             } else {
    58                 $body.removeClass( 'sidebar-fixed' );
    59             }
    60         } else {
    61             $body.removeClass( 'sidebar-fixed' );
     60        if ( 955 >= windowWidth ) {
     61            top = bottom = false;
     62            $sidebar.removeAttr( 'style' );
    6263        }
    6364    }
    6465
    65     function debouncedFixedOrScrolledSidebar() {
    66         var timeout;
    67         return function() {
    68             clearTimeout( timeout );
    69             timeout = setTimeout( function() {
    70                 timeout = null;
    71                 fixedOrScrolledSidebar();
    72             }, 150 );
    73         };
     66    function scroll() {
     67        var windowPos = $window.scrollTop();
     68
     69        if ( 955 <= windowWidth && sidebarHeight + adminbarOffset < documentHeight ) {
     70            if ( sidebarHeight + adminbarOffset > windowHeight ) {
     71                if ( windowPos > lastWindowPos ) {
     72                    if ( top ) {
     73                        top = false;
     74                        topOffset = ( $sidebar.offset().top > 0 ) ? $sidebar.offset().top - adminbarOffset : 0;
     75                        $sidebar.attr( 'style', 'top: ' + topOffset + 'px;' );
     76                    } else if ( ! bottom && windowPos + windowHeight > sidebarHeight + $sidebar.offset().top ) {
     77                        bottom = true;
     78                        $sidebar.attr( 'style', 'position: fixed;bottom: 0;' );
     79                    }
     80                } else if ( windowPos < lastWindowPos ) {
     81                    if ( bottom ) {
     82                        bottom = false;
     83                        topOffset = ( $sidebar.offset().top > 0 ) ? $sidebar.offset().top - adminbarOffset : 0;
     84                        $sidebar.attr( 'style', 'top: ' + topOffset + 'px;' );
     85                    } else if ( ! top && windowPos + adminbarOffset < $sidebar.offset().top ) {
     86                        top = true;
     87                        $sidebar.attr( 'style', 'position: fixed;' );
     88                    }
     89                } else {
     90                    top = bottom = false;
     91                    topOffset = ( $sidebar.offset().top > 0 ) ? $sidebar.offset().top - adminbarOffset : 0;
     92                    $sidebar.attr( 'style', 'top: ' + topOffset + 'px;' );
     93                }
     94            } else if ( ! top ) {
     95                top = true;
     96                $sidebar.attr( 'style', 'position: fixed;' );
     97            }
     98        }
     99
     100        lastWindowPos = windowPos;
    74101    }
    75102
     103    function resizeAndScroll() {
     104        resize();
     105        scroll();
     106    }
    76107
    77108    $( document ).ready( function() {
    78         // But! We only want to allow fixed sidebars when there are no submenus.
    79         if ( $( '#site-navigation .sub-menu' ).length ) {
    80             return;
    81         }
    82 
    83         // only initialize 'em if we need 'em
    84         $body         = $( 'body' );
    85         $window       = $( window );
    86         sidebar       = $( '#sidebar' )[0];
    87         toolbarOffset = $body.is( '.admin-bar' ) ? $( '#wpadminbar' ).height() : 0;
     109        $body          = $( 'body' );
     110        $window        = $( window );
     111        $document      = $( document );
     112        $sidebar        = $( '#sidebar' ).first();
     113        adminbarOffset = $body.is( '.admin-bar' ) ? $( '#wpadminbar' ).height() : 0;
    88114
    89115        $window
    90             .on( 'load.twentyfifteen', fixedOrScrolledSidebar )
    91             .on( 'resize.twentyfifteen', debouncedFixedOrScrolledSidebar() );
     116            .on( 'scroll.twentyfifteen', scroll )
     117            .on( 'resize.twentyfifteen', function() {
     118                clearTimeout( resizeTimer );
     119                resizeTimer = setTimeout( resizeAndScroll, 500 );
     120            } );
     121        $sidebar.on( 'click keydown', 'button', resizeAndScroll );
     122
     123        resizeAndScroll();
     124
     125        for ( var i = 1; i < 6; i++ ) {
     126            setTimeout( resizeAndScroll, 100 * i );
     127        }
    92128    } );
    93129
Note: See TracChangeset for help on using the changeset viewer.