Skip to content

Instantly share code, notes, and snippets.

@nathancahill
Last active October 6, 2016 06:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nathancahill/f7ea239306737f2075a94de33881dc2e to your computer and use it in GitHub Desktop.
Save nathancahill/f7ea239306737f2075a94de33881dc2e to your computer and use it in GitHub Desktop.
var throttle = function (callback, limit) {
var wait = false;
return function () {
if (!wait) {
callback.call();
wait = true;
setTimeout(function () {
wait = false;
}, limit);
}
}
}
var inViewport = function (element, offset) {
if ( offset === void 0 ) offset = 0;
var ref = element.getBoundingClientRect();
var top = ref.top;
var right = ref.right;
var bottom = ref.bottom;
var left = ref.left;
return bottom > offset
&& right > offset
&& window.innerWidth - left > offset
&& window.innerHeight - top > offset;
};
var inViewRegistry = function inViewRegistry(elements) {
this.current = [];
this.elements = elements;
this.handlers = { enter: [], exit: [] };
this.singles = { enter: [], exit: [] };
};
inViewRegistry.prototype.check = function check (offset) {
var this$1 = this;
this.elements.forEach(function (el) {
var passes = inViewport(el, offset);
var index = this$1.current.indexOf(el);
var current = index > -1;
var entered = passes && !current;
var exited = !passes && current;
if (entered) {
this$1.current.push(el);
this$1.emit('enter', el);
}
if (exited) {
this$1.current.splice(index, 1);
this$1.emit('exit', el);
}
});
return this;
};
inViewRegistry.prototype.on = function on (event, handler) {
this.handlers[event].push(handler);
return this;
};
inViewRegistry.prototype.once = function once (event, handler) {
this.singles[event].unshift(handler);
return this;
};
inViewRegistry.prototype.emit = function emit (event, element) {
var this$1 = this;
while(this.singles[event].length) {
this$1.singles[event].pop()(element);
}
var length = this.handlers[event].length;
while (--length > -1) {
this$1.handlers[event][length](element);
}
return this;
};
function Registry (elements) {
return new inViewRegistry(elements);
};
var inView = (function () {
// How often and on what events we should check each registry.
var threshold = 100;
var triggers = ['scroll', 'resize', 'load'];
// By default, use an offset of 0.
var offset = 0;
var selectors = { history: [] };
triggers.forEach(function (event) { return window.addEventListener(event, throttle(function () {
selectors.history.forEach(function (selector) {
selectors[selector].check(offset);
});
}, threshold)); });
var control = function (selector) {
if (typeof selector !== 'string') return;
// Get an up-to-date list of elements.
var elements = [].slice.call(document.querySelectorAll(selector));
// If the registry exists, update the elements.
if (selectors.history.indexOf(selector) > -1) {
selectors[selector].elements = elements;
}
// If it doesn't exist, create a new registry.
else {
selectors[selector] = Registry(elements);
selectors.history.push(selector);
}
return selectors[selector];
};
control.offset = function (n) {
if (typeof n === 'number') offset = n;
};
control.is = inViewport;
return control;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment