Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update jquery.visible.js #53

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 19 additions & 11 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,37 @@ This basic check will return `true` if the entire element is visible to the user

$('#element').visible();

If you'd like to check for ANY PART of the element, you can use the following:
To check to see if ANY PART of the element is visible, you can specify a paremeter ('partial').

$('#element').visible( true );
$('#element').visible({ partial: true });

The plugin ignores the elements visibility by default. E.g., `display:none`, `visibility: hidden`, `offsetWidth` or `offsetHeight` is 0).
To filter on css visibility, you can use the jQuery `:visible` selector:

$('#element:visible').visible();

Optionally, you can specify a second parameter to the `.visible` plugin, which will check whether the element is visible, as well as
whether it's within the viewport too.
Optionally, you can specify a parameter ('hidden') to the `.visible` plugin, which will check whether the element is visible, as well as whether it's within the viewport too.

$('#element:visible').visible( false, true );
$('#element:visible').visible({ hidden: true });

Optionally, you can add a third parameter to specify the direction to check for visibility. This can either be 'horizontal', 'vertical' or 'both'.
Optionally, you can add a parameter ('direction') to specify the direction to check for visibility. This can either be 'horizontal', 'vertical' or 'both'.
Default is to 'both'.

$('#element').visible( false, false, 'horizontal' );
$('#element').visible({ direction: 'horizontal' });

You can also check to see if the object is visible within a specific container by providing a parameter ('container'). The default container is the window.

$('#element').visible({ container: $('#parent') });

You can specify any combination of the parameters available when checking visibility.

To see if the item is partially visible within a parent:

$('#element').visible({ partial: true, container: $('#parent') });

To see if the item is completely horizontally visible within a parent:

$('#element').visible({ container: $('#parent'), direction: 'horizontal' });

Demos
-----
Expand All @@ -46,7 +58,3 @@ See the blog article:
- [Checking if an element is visible on-screen using jQuery](https://www.customd.com/articles/13/checking-if-an-element-is-visible-on-screen-using-jquery)


Limitations
-----------

Currently, this plugin will not check for visibility in nested scrollable areas, only on the main viewport (window object).
98 changes: 52 additions & 46 deletions jquery.visible.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(function($){
(function ($) {

/**
* Copyright 2012, Digital Fusion
Expand All @@ -10,72 +10,78 @@
* the user visible viewport of a web browser.
* can accounts for vertical position, horizontal, or both
*/
var $w=$(window);
$.fn.visible = function(partial,hidden,direction,container){
var $w = $(window);
$.fn.visible = function (options) {

if (this.length < 1)
return;

// Set direction default to 'both'.
direction = direction || 'both';

var $t = this.length > 1 ? this.eq(0) : this,
isContained = typeof container !== 'undefined' && container !== null,
$c = isContained ? $(container) : $w,
wPosition = isContained ? $c.position() : 0,
t = $t.get(0),
vpWidth = $c.outerWidth(),
vpHeight = $c.outerHeight(),
clientSize = hidden === true ? t.offsetWidth * t.offsetHeight : true;
// set defaults into options object
var defaults = {
partial: false,
hidden: false,
direction: 'both', // Set direction default to 'both'.
container: null
};
// merge defaults and provided arguments
var opts = $.extend({}, defaults, options);

if (typeof t.getBoundingClientRect === 'function'){
var $t = this.length > 1 ? this.eq(0) : this,
isContained = typeof opts.container !== 'undefined' && opts.container !== null,
$c = isContained ? $(opts.container) : $w,
wPosition = isContained ? $c.position() : 0,
t = $t.get(0),
vpWidth = $c.outerWidth(),
vpHeight = $c.outerHeight(),
clientSize = opts.hidden === true ? t.offsetWidth * t.offsetHeight : true;

if (typeof t.getBoundingClientRect === 'function') {

// Use this native browser method, if available.
var rec = t.getBoundingClientRect(),
tViz = isContained ?
rec.top - wPosition.top >= 0 && rec.top < vpHeight + wPosition.top :
rec.top >= 0 && rec.top < vpHeight,
rec.top - wPosition.top >= 0 && rec.top < vpHeight + wPosition.top :
rec.top >= 0 && rec.top < vpHeight,
bViz = isContained ?
rec.bottom - wPosition.top > 0 && rec.bottom <= vpHeight + wPosition.top :
rec.bottom > 0 && rec.bottom <= vpHeight,
rec.bottom - wPosition.top > 0 && rec.bottom <= vpHeight + wPosition.top :
rec.bottom > 0 && rec.bottom <= vpHeight,
lViz = isContained ?
rec.left - wPosition.left >= 0 && rec.left < vpWidth + wPosition.left :
rec.left >= 0 && rec.left < vpWidth,
rec.left - wPosition.left >= 0 && rec.left < vpWidth + wPosition.left :
rec.left >= 0 && rec.left < vpWidth,
rViz = isContained ?
rec.right - wPosition.left > 0 && rec.right < vpWidth + wPosition.left :
rec.right > 0 && rec.right <= vpWidth,
vVisible = partial ? tViz || bViz : tViz && bViz,
hVisible = partial ? lViz || rViz : lViz && rViz,
vVisible = (rec.top < 0 && rec.bottom > vpHeight) ? true : vVisible,
rec.right - wPosition.left > 0 && rec.right < vpWidth + wPosition.left :
rec.right > 0 && rec.right <= vpWidth,
vVisible = opts.partial ? tViz || bViz : tViz && bViz,
hVisible = opts.partial ? lViz || rViz : lViz && rViz,
vVisible = (rec.top < 0 && rec.bottom > vpHeight) ? true : vVisible,
hVisible = (rec.left < 0 && rec.right > vpWidth) ? true : hVisible;

if(direction === 'both')
if (opts.direction === 'both')
return clientSize && vVisible && hVisible;
else if(direction === 'vertical')
else if (opts.direction === 'vertical')
return clientSize && vVisible;
else if(direction === 'horizontal')
else if (opts.direction === 'horizontal')
return clientSize && hVisible;
} else {

var viewTop = isContained ? 0 : wPosition,
viewBottom = viewTop + vpHeight,
viewLeft = $c.scrollLeft(),
viewRight = viewLeft + vpWidth,
position = $t.position(),
_top = position.top,
_bottom = _top + $t.height(),
_left = position.left,
_right = _left + $t.width(),
compareTop = partial === true ? _bottom : _top,
compareBottom = partial === true ? _top : _bottom,
compareLeft = partial === true ? _right : _left,
compareRight = partial === true ? _left : _right;
var viewTop = isContained ? 0 : wPosition,
viewBottom = viewTop + vpHeight,
viewLeft = $c.scrollLeft(),
viewRight = viewLeft + vpWidth,
position = $t.position(),
_top = position.top,
_bottom = _top + $t.height(),
_left = position.left,
_right = _left + $t.width(),
compareTop = opts.partial === true ? _bottom : _top,
compareBottom = opts.partial === true ? _top : _bottom,
compareLeft = opts.partial === true ? _right : _left,
compareRight = opts.partial === true ? _left : _right;

if(direction === 'both')
if (opts.direction === 'both')
return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop)) && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
else if(direction === 'vertical')
else if (opts.direction === 'vertical')
return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop));
else if(direction === 'horizontal')
else if (opts.direction === 'horizontal')
return !!clientSize && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
}
};
Expand Down