is element in viewport

by Laurens Maneschijn

HTML

<span id="target"></span>

<div id="menu">
    <button id="loop_stop">stop</button>
    <button id="loop_start">start</button>
    <label>automove:
        <input type="checkbox" id="automove">
    </label>
    <br>
    <label>x:
        <input type="range" id="range_x" min="-1" max="1" step="0.1">
    </label>
    <br>
    <label>y:
        <input type="range" id="range_y" min="-1" max="1" step="0.1">
    </label>
    <br>
    <hr>
    <pre id="log"></pre>
</div>

CSS

#target {
    position: absolute;
    display: block;
    width: 200px;
    height: 200px;
    background: rgba(0, 0, 255, 0.1);
    border: 2px dashed #ff00ff;
    text-align: center;
}

#menu {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 9;
}
input{
	vertical-align: middle;
}

JavaScript

function ElementPositionRelativeOfWindow(element){
	this.element = element;
	this.autoupdate = false;
	this.update();
}
ElementPositionRelativeOfWindow.prototype.element = null;
ElementPositionRelativeOfWindow.prototype.autoupdate = false;
ElementPositionRelativeOfWindow.prototype.getElementBoundingClientRect = function(el){
	// getBoundingClientRect() is the key functionality;
	// figure out the position of the element, in relation to the current viewport.
	// top   : position of top    edge of element relative to top  edge of viewport
	// bottom: position of bottom edge of element relative to top  edge of viewport
	// left  : position of left   edge of element relative to left edge of viewport
	// right : position of right  edge of element relative to left edge of viewport
	if (el && el.getBoundingClientRect) {
		return el.getBoundingClientRect();
	}
	// TODO fallback to calculating the same using document offset and scrolling etc.
	
	// NB: below is returned too if element is not visible
	return {
		top: 0,
		right: 0,
		bottom: 0,
		left: 0,
		width: 0,
		height: 0
	};
}
ElementPositionRelativeOfWindow.prototype.update = function(){
	this.bounding_client_rect = this.getElementBoundingClientRect(this.element);
	this.window_size_x = parseInt($(window).width() || window.innerWidth, 10);
	this.window_size_y = parseInt($(window).height() || window.innerHeight, 10);
}
ElementPositionRelativeOfWindow.prototype.autoUpdateIfNeeded = function(){
	if (this.autoupdate) {
		this.update();
	}
}
ElementPositionRelativeOfWindow.prototype.isFullyAbove = function(){
	this.autoUpdateIfNeeded();
	return this.bounding_client_rect.bottom < 0;
}
ElementPositionRelativeOfWindow.prototype.isFullyBelow = function(){
	this.autoUpdateIfNeeded();
	return this.bounding_client_rect.top > this.window_size_y;
}
ElementPositionRelativeOfWindow.prototype.isFullyLeftOf = function(){
	this.autoUpdateIfNeeded();
	return this.bounding_client_rect.right <...