diff --git a/README.markdown b/README.markdown index f238166..f25dfbe 100644 --- a/README.markdown +++ b/README.markdown @@ -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 ----- @@ -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). diff --git a/jquery.visible.js b/jquery.visible.js index 1d449c3..fc2dfed 100644 --- a/jquery.visible.js +++ b/jquery.visible.js @@ -1,4 +1,4 @@ -(function($){ +(function ($) { /** * Copyright 2012, Digital Fusion @@ -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)); } };