Offset Exp. 3

by Brian Burns

HTML

<div id="display">scroll down</div>
<div id="overflow">
  <div class="dead-space"></div>
  <div id="offset"></div>
  <div class="dead-space"></div>
</div>

CSS

* {margin:0; padding:0;} /* just to make things pretty */
div {z-index:1; position:relative; width:100%;}
div.dead-space {height:2000px; background-color:grey;}
#overflow {position:absolute; top:100px; left:0px; height:calc(100% - 100px); box-sizing:border-box; overflow-y:scroll;}
#offset {height:100px; background-color:aqua;}
#display {z-index:2; position:fixed; top:10px; left:0px; text-align:center; color:black; font-size:20px;}

JavaScript

var v = $('#overflow'), 	// window (i.e. element with overflow-y:scroll;)
  	e = $('#offset'),			// element
    d = $('#display');		// display for text
    
v.scroll(function(){
	d.text("div#offset is " + betterOffset(false, e, v) + "px from top");
});

/*
function: betterOffset
hint: Allows you to calculate dynamic and static offset whether they are in a div container with overscroll or not.

            name:           type:               option:         notes:
@param      s (static)      boolean             required        default: true | set false for dynamic
@param      e (element)     string or object    required
@param      v (viewer)      string or object    optional        If you leave this out, it will use $(window) by default. What I am calling the 'viewer' is the thing that scrolls (i.e. The element with "overflow-y:scroll;" style.).

@return                  numeric
*/
function betterOffset(s, e, v) {
    // Set Defaults
        s = (typeof s == 'boolean') ? s : true;
        e = (typeof e == 'object') ? e : $(e);
        if (v != undefined) {v = (typeof v == 'object') ? v : $(v);} else {v = false;}

    // Set Variables
        var w = $(window),              // window object
            wp = w.scrollTop(),         // window position
            eo = e.offset().top;        // element offset
        if (v) {
            var vo = v.offset().top,    // viewer offset
                vp = v.scrollTop();     // viewer position
        }

    // Calculate
        if (s) {
            return (v) ? (eo - vo) + vp : eo;
        } else {
            return (v) ? eo - vo : eo - wp;
        }
}