176 lines
4.3 KiB
JavaScript
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); |