Skip to content

Instantly share code, notes, and snippets.

@HoraceShmorace
Last active October 7, 2015 12:39
Show Gist options
  • Save HoraceShmorace/d33ee68a37bf4f47eff6 to your computer and use it in GitHub Desktop.
Save HoraceShmorace/d33ee68a37bf4f47eff6 to your computer and use it in GitHub Desktop.
/**
* Calculates whether an HTML element has been viewed, according to the criteria in the options argument.
* @param {Object} options An object with the following properties:
* minArean {Number} The minimum % of visible area to qualify as viewed.
* minWidth {Number} The minimum % of visible width to qualify as viewed.
* minHeight {Number} The minimum % of visible height to qualify as viewed.
* @param {Function} next An optional callback function.
* @returns {Boolean} Whether the element has been viewed.
*/
var checkIsViewed = function(options, next) {
var $element = options.element,
isViewed;
if (typeof $element === "string") $element = $("#" + $element);
if ($element) {
var isViewed,
result,
minArea = options.minArea || 0,
minWidth = options.minWidth || 0,
minHeight = options.minHeight || 0,
viewportHeight = $(window).height(),
viewportWidth = $(window).width(),
scrollTop = $(window).scrollTop(),
scrollLeft = $(window).scrollLeft(),
scrollBottom = viewportHeight + scrollTop,
scrollRight = viewportWidth + scrollLeft,
elementTop = $element.offset().top,
elementLeft = $element.offset().left,
elementHeight = $element.height(),
elementWidth = $element.width(),
elementArea = elementHeight * elementWidth,
viewedWidth = scrollLeft < elementLeft ? Math.min(Math.max(scrollRight - elementLeft, 0), elementWidth) : Math.max(elementWidth - (scrollLeft - elementLeft), 0),
viewedWidthPercentage = Math.round(viewedWidth / elementWidth * 1000) / 10,
viewedHeight = scrollTop < elementTop ? Math.min(Math.max(scrollBottom - elementTop, 0), elementHeight) : Math.max(elementHeight - (scrollTop - elementTop), 0),
viewedHeightPercentage = Math.round(viewedHeight / elementHeight * 1000) / 10,
viewedArea = viewedWidth * viewedHeight,
viewedAreaPercentage = Math.round(viewedArea / elementArea * 1000) / 10;
isViewed = viewedAreaPercentage > minArea && viewedWidthPercentage > minWidth && viewedHeightPercentage > minHeight && $element.not(":hidden");
result = {
isViewed: isViewed,
viewedArea: viewedArea,
viewedAreaPercentage: viewedAreaPercentage,
viewedWidth: viewedWidth,
viewedWidthPercentage: viewedWidthPercentage,
viewedHeight: viewedHeight,
viewedHeightPercentage: viewedHeightPercentage,
$element: $element,
options: options
};
}
if (typeof next === "function") next(result);
return result;
};
/*** SAMPLE IMPLEMENTATION FOLLOWS... ***/
/**
* Configure options.
*/
var options = {
element: "my-element-id or jQuery('#my-element-id') object",
minArea: 50, // Must view 50% of the area.
minWidth: 25, // Must view 25% of the width.
minHeight: 25 // Must view 25% of the height.
};
/**
* Define callback function.
* This would be a great place to execute an ad call ;)
*/
var onCheckIsViewed = function(element, isViewed, viewedAreaPercentage, viewedAreaPixels) {
if (result.isViewed) {
// Do something...
} else {
// Do something else...
}
};
/**
* Defining this in a function allows you to trigger it on mulitiple events.
* In this case, window.scroll, and it also makes sense to call in document.ready.
* You could also just execute the call: checkIsViewed(options, onCheckIsViewed);
*/
var doCheckIsViewed = function() {
checkIsViewed(options, onCheckIsViewed);
};
$(window).scroll(doCheckIsViewed);
$(document).ready(doCheckIsViewed);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment