UNPKG

5.02 kBJavaScriptView Raw
1/**
2 * Most Visible v1.4.0
3 *
4 * @author Andy Palmer <andy@andypalmer.me>
5 * @license MIT
6 */
7
8(function (root, factory) {
9 // Universal Module Definition
10 /* jshint strict:false */
11 /* global define: false, module: false */
12 if (typeof define === 'function' && define.amd) {
13 define([], function () {
14 return factory(root);
15 });
16 } else if (typeof module === 'object' && module.exports) {
17 module.exports = factory(root);
18 } else {
19 root.mostVisible = factory(root);
20 }
21}(typeof self !== 'undefined' ? self : this, function (window) {
22 /* jshint unused: vars */
23
24 'use strict';
25
26 /**
27 * MostVisible constructor
28 *
29 * @param {NodeList|string} elements
30 * @param {Object} options
31 * @constructor
32 */
33 function MostVisible(elements, options) {
34 if (!(this instanceof MostVisible)) {
35 return (new MostVisible(elements, options)).getMostVisible();
36 }
37
38 if (typeof elements === 'string') {
39 elements = document.querySelectorAll(elements);
40 }
41
42 this.elements = elements;
43 this.options = extend({}, MostVisible.defaults, options);
44 }
45
46 /**
47 * MostVisible default options
48 *
49 * @namespace
50 * @property {object} defaults Default options hash.
51 * @property {boolean} defaults.percentage Whether to calculate visibility as a percentage of height.
52 * @property {number} defaults.offset An offset to take into account when calculating visibility.
53 */
54 MostVisible.defaults = {
55 percentage: false,
56 offset: 0
57 };
58
59 MostVisible.prototype = {
60 /**
61 * Returns the most visible element from the instance's NodeList.
62 *
63 * @returns {Element} Most visible element.
64 */
65 getMostVisible: function () {
66 var element = null,
67 viewportHeight = document.documentElement.clientHeight,
68 maxVisible = 0;
69
70 for (var i = 0; i < this.elements.length; i++) {
71 var currentVisible = this.getVisibleHeight(this.elements[i], viewportHeight);
72
73 if (currentVisible > maxVisible) {
74 maxVisible = currentVisible;
75 element = this.elements[i];
76 }
77 }
78
79 return element;
80 },
81
82 /**
83 * Returns the visible height of an element.
84 *
85 * @param {Element} element Element to check the visibility of.
86 * @param {number} viewportHeight
87 * @returns {number} Visible height of the element in pixels or a percentage of the element's total height.
88 */
89 getVisibleHeight: function (element, viewportHeight) {
90 var rect = element.getBoundingClientRect(),
91 rectTopOffset = rect.top - this.options.offset,
92 rectBottomOffset = rect.bottom - this.options.offset,
93 height = rect.bottom - rect.top,
94 visible = {
95 top: rectTopOffset >= 0 && rectTopOffset < viewportHeight,
96 bottom: rectBottomOffset > 0 && rectBottomOffset < viewportHeight
97 },
98 visiblePx = 0;
99
100 if (visible.top && visible.bottom) {
101 // Whole element is visible
102 visiblePx = height;
103 } else if (visible.top) {
104 visiblePx = viewportHeight - rect.top;
105 } else if (visible.bottom) {
106 visiblePx = rectBottomOffset;
107 } else if (height > viewportHeight && rectTopOffset < 0) {
108 var absTop = Math.abs(rectTopOffset);
109
110 if (absTop < height) {
111 // Part of the element is visible
112 visiblePx = height - absTop;
113 }
114 }
115
116 if (this.options.percentage) {
117 return (visiblePx / height) * 100;
118 }
119
120 return visiblePx;
121 }
122 };
123
124 /*
125 MostVisible.makeJQueryPlugin = function ($) {
126 if (!$) {
127 return;
128 }
129
130 $.fn.mostVisible = function (options) {
131 var instance = new MostVisible(this.get(), options);
132 return this.filter(instance.getMostVisible());
133 };
134 };
135 */
136
137 // Try adding the jQuery plugin to window.jQuery
138 // MostVisible.makeJQueryPlugin(window.jQuery);
139
140 /**
141 * Extends obj by adding the properties of all other objects passed to the function.
142 *
143 * @param {...Object} obj
144 * @returns {Object} The extended object.
145 */
146 function extend(obj) {
147 for (var i = 1; i < arguments.length; i++) {
148 for (var key in arguments[i]) {
149 if (arguments[i].hasOwnProperty(key)) {
150 obj[key] = arguments[i][key];
151 }
152 }
153 }
154
155 return obj;
156 }
157
158 //noinspection JSAnnotator
159 return MostVisible;
160
161}));