www.lightcourse.com/public/static/home/js/waypoints.js

176 lines
4.3 KiB
JavaScript

(function($, wp, wps, window, undefined) {
'$:nomunge';
var $w = $(window),
waypoints = [],
oldScroll = -99999,
didScroll = false,
didResize = false,
eventName = 'waypoint.reached',
methods = {
init: function(f, options) {
this.each(function() {
var $this = $(this),
ndx = waypointIndex($this),
base = ndx < 0 ? $.fn[wp].defaults: waypoints[ndx].options,
opts = $.extend({},
base, options);
opts.offset = opts.offset === "bottom-in-view" ?
function() {
return $[wps]('viewportHeight') - $(this).outerHeight();
}: opts.offset;
if (ndx < 0) {
waypoints.push({
element: $this,
offset: $this.offset().top,
options: opts
});
}
else {
waypoints[ndx].options = opts;
}
f && $this.bind(eventName, f);
});
$[wps]('refresh');
return this;
},
remove: function() {
return this.each(function() {
var ndx = waypointIndex($(this));
if (ndx >= 0) {
waypoints.splice(ndx, 1);
}
});
},
destroy: function() {
return this.unbind(eventName)[wp]('remove');
}
};
function waypointIndex(el) {
var i = waypoints.length - 1;
while (i >= 0 && waypoints[i].element[0] !== el[0]) {
i -= 1;
}
return i;
}
function triggerWaypoint(way, dir) {
way.element.trigger(eventName, dir)
if (way.options.triggerOnce) {
way.element[wp]('destroy');
}
}
function doScroll() {
var newScroll = $w.scrollTop(),
isDown = newScroll > oldScroll,
pointsHit = $.grep(waypoints,
function(el, i) {
return isDown ? (el.offset > oldScroll && el.offset <= newScroll) : (el.offset <= oldScroll && el.offset > newScroll);
});
if (!oldScroll || !newScroll) {
$[wps]('refresh');
}
oldScroll = newScroll;
if (!pointsHit.length) return;
if ($[wps].settings.continuous) {
$.each(isDown ? pointsHit: pointsHit.reverse(),
function(i, point) {
triggerWaypoint(point, [isDown ? 'down': 'up']);
});
}
else {
triggerWaypoint(pointsHit[isDown ? pointsHit.length - 1: 0], [isDown ? 'down': 'up']);
}
}
$.fn[wp] = function(method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
}
else if (typeof method === "function" || !method) {
return methods.init.apply(this, arguments);
}
else if (typeof method === "object") {
return methods.init.apply(this, [null, method]);
}
else {
$.error('Method ' + method + ' does not exist on jQuery' + wp);
}
};
$.fn[wp].defaults = {
offset: 0,
triggerOnce: false
};
var jQMethods = {
refresh: function() {
$.each(waypoints,
function(i, o) {
var adjustment = 0,
oldOffset = o.offset;
if (typeof o.options.offset === "function") {
adjustment = o.options.offset.apply(o.element);
}
else if (typeof o.options.offset === "string") {
var amount = parseFloat(o.options.offset),
adjustment = o.options.offset.indexOf("%") ? Math.ceil($[wps]('viewportHeight') * (amount / 100)) : amount;
}
else {
adjustment = o.options.offset;
}
o.offset = o.element.offset().top - adjustment;
if (oldScroll > oldOffset && oldScroll <= o.offset) {
triggerWaypoint(o, ['up']);
}
else if (oldScroll < oldOffset && oldScroll >= o.offset) {
triggerWaypoint(o, ['down']);
}
});
waypoints.sort(function(a, b) {
return a.offset - b.offset;
});
},
viewportHeight: function() {
return (window.innerHeight ? window.innerHeight: $w.height());
},
aggregate: function() {
var points = $();
$.each(waypoints,
function(i, e) {
points = points.add(e.element);
});
return points;
}
};
$[wps] = function(method) {
if (jQMethods[method]) {
return jQMethods[method].apply(this);
}
else {
return jQMethods["aggregate"]();
}
};
$[wps].settings = {
continuous: true,
resizeThrottle: 200,
scrollThrottle: 100
};
$w.scroll(function() {
if (!didScroll) {
didScroll = true;
window.setTimeout(function() {
doScroll();
didScroll = false;
},
$[wps].settings.scrollThrottle);
}
}).resize(function() {
if (!didResize) {
didResize = true;
window.setTimeout(function() {
$[wps]('refresh');
didResize = false;
},
$[wps].settings.resizeThrottle);
}
}).load(function() {
$[wps]('refresh');
doScroll();
});
})(jQuery, 'waypoint', 'waypoints', this);