jQuery plugin "jStickyScrolledPanel"

by jasonkylefrank

HTML

<div id="top" 
     style="width:100%; height:100px; background:#ccc; margin:0;">
   Top Panel
</div>

<div id="stickyBar" class="barToBecomeSticky clearfix">
   Sticky Panel
    <span id="ExpandButton">Expand / Contract</span> 
    <span id="SearchOptions" style="display: none;">
        <span>
            <label><input type="checkbox"/>Checkbox 1</label>
        </span>
        <span>
            <label><input type="checkbox" />Checkbox 2</label>
        </span>
    </span> 
</div>

<div id="content" 
     style="width: 100%; height: 1000px; background: #ccc; margin: 0;">
   Content Panel
   
    <div>1</div><div>2</div><div>3</div><div>4</div><div>5</div>
         
    This panel will not jump when the sticky panel becomes stuck.
    <br/><br/>
    <div>a</div><div>b</div><div>c</div><div>d</div><div>e</div>
    <div>f</div><div>g</div><div>h</div>
</div>

CSS

/* Need this selector to have higher precedence
   (for now, until I can add these properties via JS. */
div.stickToTop { 
    position:fixed; top:0;
    /* --- These settings make the element 
           mimic a "width:100%" behavior.
       --- */
    /* TODO: use JS to set these b/c
       they may need to be whatever the          
       parent's margin is (and maybe 
       padding too)*/
    margin-left:8px;
    margin-right:8px;
    /* It seems that we need to include the
       left:0 and right:0 for the margin values
       to have any effect. Also, since this element
       is now fixed, positive left/right values 
       don't have any effect (need margin for that).*/
    left: 0px; right: 0px;
    width: auto;
}

.barToBecomeSticky {
    color: white;
    margin: 45px 0px 45px 0px;
    /* These values test whether or not the made-sticky
       version can mimic the layout placement */
    margin-left: 12px; margin-right:12px;
    padding: 3px;
    background: green;


    border: 5px solid #55aa55;
}

#ExpandButton {
    font-size: 12px;
    border: 1px solid #aaa;
    background: #005500;
    color: #ccc;
    float: right;
    margin: 3px; 
    padding-left: 3px; padding-right: 3px;
    cursor: pointer;
}
#SearchOptions {
    display: block;
    font-size: 12px;
    margin-top: 10px;
}
#SearchOptions span { display: block; }

/* Fixes problem of floated elements expanding out of non-floated parent elements. Apply class='clearfix' to the parent container element. See: http://stackoverflow.com/a/11597829/718325 */
.clearfix:after 
{ 
   content: " ";
   display: block; 
   height: 0; 
   clear: both;
}

JavaScript

/*  jQuery.jStickyScrolledPanel
*   ----------------------
*   Version: 0.1
*   Date: 5/12/14
*   Copyright (c) 2014 Jason Frank      
*   Licensed under the MIT License
*   Description: This plugin makes an element stick to the top of the screen once it has been scrolled
*                to the top, and then restores it to its non-sticky state when scrolling should return it
*                to its normal position. It turns the element into a fixed position element to create a smooth 
*                "scroll-under" experience, while also managing its size and horizontal positioning 
*                (due to window resizing or scroll events) to make it appear that the sticky element is 
*                obeying natural layout changes. This behavior allows you to use the sticky element as a
*                "header bar" which would normally (when it is not sticky) align with content below.
*                Another way that this behavior is implemented is by being able to mimick the width of 
*                another element (i.e., the "header bar's" "content") when window resizing occurs.
*   Notes: This version only supports "Window Scrolling". Future versions may also support the ability
*          to make the element sticky in a parent-scrolled container.
*/
// Create a closure.
;(function ($, window, undefined) {
    'use strict';

    var name = 'jStickyScrolledPanel',
		id = 0,
		defaults = {
		    // A distance from the top of the screen that you want the sticky point to start at. Set to either a
		    //  pixel number or a jQuery object of an element whose outer height (at the time that the element becomes
		    //  sticky) you want to use as the offset.            
		    stickyTopOffsetOrElement: 0,
            // The CSS Z-index value to apply to the element when it is made sticky.
            stickyZIndex: 100,
		    // Callback functions for events
		    //   $spacerPanel is a helper panel that gets generated and inserted before the...