https://www.mediawiki.org/wiki/Special:Code/MediaWiki/114577
Revision: 114577
Author: raindrift
Date: 2012-03-28 21:37:23 +0000 (Wed, 28 Mar 2012)
Log Message:
-----------
adding waypoints jquery extension for working with window scroll position
Added Paths:
-----------
trunk/extensions/PageTriage/modules/external/jquery.waypoints.js
Added: trunk/extensions/PageTriage/modules/external/jquery.waypoints.js
===================================================================
--- trunk/extensions/PageTriage/modules/external/jquery.waypoints.js
(rev 0)
+++ trunk/extensions/PageTriage/modules/external/jquery.waypoints.js
2012-03-28 21:37:23 UTC (rev 114577)
@@ -0,0 +1,666 @@
+/*!
+jQuery Waypoints - v1.1.5
+Copyright (c) 2011-2012 Caleb Troughton
+Dual licensed under the MIT license and GPL license.
+https://github.com/imakewebthings/jquery-waypoints/blob/master/MIT-license.txt
+https://github.com/imakewebthings/jquery-waypoints/blob/master/GPL-license.txt
+*/
+
+/*
+Waypoints is a small jQuery plugin that makes it easy to execute a function
+whenever you scroll to an element.
+
+GitHub Repository: https://github.com/imakewebthings/jquery-waypoints
+Documentation and Examples: http://imakewebthings.github.com/jquery-waypoints
+
+Changelog:
+ v1.1.5
+ - Make plugin compatible with Browserify/RequireJS. (Thanks @cjroebuck)
+ v1.1.4
+ - Add handler option to give alternate binding method. (Issue #34)
+ v1.1.3
+ - Fix cases where waypoints are added post-load and should be
triggered
+ immediately. (Issue #28)
+ v1.1.2
+ - Fixed error thrown by waypoints with triggerOnce option that
were
+ triggered via resize refresh.
+ v1.1.1
+ - Fixed bug in initialization where all offsets were being
calculated
+ as if set to 0 initially, causing unwarranted triggers during
the
+ subsequent refresh.
+ - Added onlyOnScroll, an option for individual waypoints that
disables
+ triggers due to an offset refresh that crosses the current
scroll
+ point. (All credit to @knuton on this one.)
+ v1.1
+ - Moved the continuous option out of global settings and into
the options
+ object for individual waypoints.
+ - Added the context option, which allows for using waypoints
within any
+ scrollable element, not just the window.
+ v1.0.2
+ - Moved scroll and resize handler bindings out of load. Should
play nicer
+ with async loaders like Head JS and LABjs.
+ - Fixed a 1px off error when using certain % offsets.
+ - Added unit tests.
+ v1.0.1
+ - Added $.waypoints('viewportHeight').
+ - Fixed iOS bug (using the new viewportHeight method).
+ - Added offset function alias: 'bottom-in-view'.
+ v1.0
+ - Initial release.
+
+Support:
+ - jQuery versions 1.4.3+
+ - IE6+, FF3+, Chrome 6+, Safari 4+, Opera 11
+ - Other versions and browsers may work, these are just the ones I've
looked at.
+*/
+
+(function($, wp, wps, window, undefined){
+ '$:nomunge';
+
+ var $w = $(window),
+
+ // Keeping common strings as variables = better minification
+ eventName = 'waypoint.reached',
+
+ /*
+ For the waypoint and direction passed in, trigger the waypoint.reached
+ event and deal with the triggerOnce option.
+ */
+ triggerWaypoint = function(way, dir) {
+ way.element.trigger(eventName, dir);
+ if (way.options.triggerOnce) {
+ way.element[wp]('destroy');
+ }
+ },
+
+ /*
+ Given a jQuery element and Context, returns the index of that element
in the waypoints
+ array. Returns the index, or -1 if the element is not a waypoint.
+ */
+ waypointIndex = function(el, context) {
+ var i = context.waypoints.length - 1;
+ while (i >= 0 && context.waypoints[i].element[0] !== el[0]) {
+ i -= 1;
+ }
+ return i;
+ },
+
+ // Private list of all elements used as scrolling contexts for
waypoints.
+ contexts = [],
+
+ /*
+ Context Class - represents a scrolling context. Properties include:
+ element: jQuery object containing a single HTML element.
+ waypoints: Array of waypoints operating under this scroll
context.
+ oldScroll: Keeps the previous scroll position to determine
scroll direction.
+ didScroll: Flag used in scrolling the context's scroll event.
+ didResize: Flag used in scrolling the context's resize event.
+ doScroll: Function that checks for crossed waypoints. Called
from throttler.
+ */
+ Context = function(context) {
+ $.extend(this, {
+ element: $(context),
+ oldScroll: 0,
+
+ /*
+ List of all elements that have been registered as
waypoints.
+ Each object in the array contains:
+ element: jQuery object containing a single HTML
element.
+ offset: The window scroll offset, in px, that
triggers the waypoint event.
+ options: Options object that was passed to the
waypoint fn function.
+ */
+ 'waypoints': [],
+
+ didScroll: false,
+ didResize: false,
+
+ doScroll: $.proxy(function() {
+ var newScroll = this.element.scrollTop(),
+
+ // Are we scrolling up or down? Used for
direction argument in callback.
+ isDown = newScroll > this.oldScroll,
+ that = this,
+
+ // Get a list of all waypoints that were
crossed since last scroll move.
+ pointsHit = $.grep(this.waypoints, function(el,
i) {
+ return isDown ?
+ (el.offset > that.oldScroll &&
el.offset <= newScroll) :
+ (el.offset <= that.oldScroll &&
el.offset > newScroll);
+ }),
+ len = pointsHit.length;
+
+ // iOS adjustment
+ if (!this.oldScroll || !newScroll) {
+ $[wps]('refresh');
+ }
+
+ // Done with scroll comparisons, store new
scroll before ejection
+ this.oldScroll = newScroll;
+
+ // No waypoints crossed? Eject.
+ if (!len) return;
+
+ // If several waypoints triggered, need to do
so in reverse order going up
+ if (!isDown) pointsHit.reverse();
+
+ /*
+ One scroll move may cross several waypoints.
If the waypoint's continuous
+ option is true it should fire even if it isn't
the last waypoint. If false,
+ it will only fire if it's the last one.
+ */
+ $.each(pointsHit, function(i, point) {
+ if (point.options.continuous || i ===
len - 1) {
+ triggerWaypoint(point, [isDown
? 'down' : 'up']);
+ }
+ });
+ }, this)
+ });
+
+ // Setup scroll and resize handlers. Throttled at the
settings-defined rate limits.
+ $(context).scroll($.proxy(function() {
+ if (!this.didScroll) {
+ this.didScroll = true;
+ window.setTimeout($.proxy(function() {
+ this.doScroll();
+ this.didScroll = false;
+ }, this), $[wps].settings.scrollThrottle);
+ }
+ }, this)).resize($.proxy(function() {
+ if (!this.didResize) {
+ this.didResize = true;
+ window.setTimeout($.proxy(function() {
+ $[wps]('refresh');
+ this.didResize = false;
+ }, this), $[wps].settings.resizeThrottle);
+ }
+ }, this));
+
+ $w.load($.proxy(function() {
+ /*
+ Fire a scroll check, should the page be loaded at a
non-zero scroll value,
+ as with a fragment id link or a page refresh.
+ */
+ this.doScroll();
+ }, this));
+ },
+
+ /* Returns a Context object from the contexts array, given the raw HTML
element
+ for that context. */
+ getContextByElement = function(element) {
+ var found = null;
+
+ $.each(contexts, function(i, c) {
+ if (c.element[0] === element) {
+ found = c;
+ return false;
+ }
+ });
+
+ return found;
+ },
+
+ // Methods exposed to the effin' object
+ methods = {
+ /*
+ jQuery.fn.waypoint([handler], [options])
+
+ handler
+ function, optional
+ A callback function called when the user scrolls past
the element.
+ The function signature is function(event, direction)
where event is
+ a standard jQuery Event Object and direction is a
string, either 'down'
+ or 'up' indicating which direction the user is
scrolling.
+
+ options
+ object, optional
+ A map of options to apply to this set of waypoints,
including where on
+ the browser window the waypoint is triggered. For a
full list of
+ options and their defaults, see $.fn.waypoint.defaults.
+
+ This is how you register an element as a waypoint. When the
user scrolls past
+ that element it triggers waypoint.reached, a custom event.
Since the
+ parameters for creating a waypoint are optional, we have a few
different
+ possible signatures. Let’s look at each of them.
+
+ someElements.waypoint();
+
+ Calling .waypoint with no parameters will register the elements
as waypoints
+ using the default options. The elements will fire the
waypoint.reached event,
+ but calling it in this way does not bind any handler to the
event. You can
+ bind to the event yourself, as with any other event, like so:
+
+ someElements.bind('waypoint.reached', function(event,
direction) {
+ // make it rain
+ });
+
+ You will usually want to create a waypoint and immediately bind
a function to
+ waypoint.reached, and can do so by passing a handler as the
first argument to
+ .waypoint:
+
+ someElements.waypoint(function(event, direction) {
+ if (direction === 'down') {
+ // do this on the way down
+ }
+ else {
+ // do this on the way back up through the waypoint
+ }
+ });
+
+ This will still use the default options, which will trigger the
waypoint when
+ the top of the element hits the top of the window. We can pass
.waypoint an
+ options object to customize things:
+
+ someElements.waypoint(function(event, direction) {
+ // do something amazing
+ }, {
+ offset: '50%' // middle of the page
+ });
+
+ You can also pass just an options object.
+
+ someElements.waypoint({
+ offset: 100 // 100px from the top
+ });
+
+ This behaves like .waypoint(), in that it registers the
elements as waypoints
+ but binds no event handlers.
+
+ Calling .waypoint on an existing waypoint will extend the
previous options.
+ If the call includes a handler, it will be bound to
waypoint.reached without
+ unbinding any other handlers.
+ */
+ init: function(f, options) {
+ // Register each element as a waypoint, add to array.
+ this.each(function() {
+ var cElement = $.fn[wp].defaults.context,
+ context,
+ $this = $(this);
+
+ // Default window context or a specific element?
+ if (options && options.context) {
+ cElement = options.context;
+ }
+
+ // Find the closest element that matches the
context
+ if (!$.isWindow(cElement)) {
+ cElement = $this.closest(cElement)[0];
+ }
+ context = getContextByElement(cElement);
+
+ // Not a context yet? Create and push.
+ if (!context) {
+ context = new Context(cElement);
+ contexts.push(context);
+ }
+
+ // Extend default and preexisting options
+ var ndx = waypointIndex($this, context),
+ base = ndx < 0 ? $.fn[wp].defaults :
context.waypoints[ndx].options,
+ opts = $.extend({}, base, options);
+
+ // Offset aliases
+ opts.offset = opts.offset === "bottom-in-view" ?
+ function() {
+ var cHeight =
$.isWindow(cElement) ? $[wps]('viewportHeight')
+ : $(cElement).height();
+ return cHeight -
$(this).outerHeight();
+ } : opts.offset;
+
+ // Update, or create new waypoint
+ if (ndx < 0) {
+ context.waypoints.push({
+ 'element': $this,
+ 'offset': null,
+ 'options': opts
+ });
+ }
+ else {
+ context.waypoints[ndx].options = opts;
+ }
+
+ // Bind the function if it was passed in.
+ if (f) {
+ $this.bind(eventName, f);
+ }
+ // Bind the function in the handler option if
it exists.
+ if (options && options.handler) {
+ $this.bind(eventName, options.handler);
+ }
+ });
+
+ // Need to re-sort+refresh the waypoints array after
new elements are added.
+ $[wps]('refresh');
+
+ return this;
+ },
+
+
+ /*
+ jQuery.fn.waypoint('remove')
+
+ Passing the string 'remove' to .waypoint unregisters the
elements as waypoints
+ and wipes any custom options, but leaves the waypoint.reached
events bound.
+ Calling .waypoint again in the future would reregister the
waypoint and the old
+ handlers would continue to work.
+ */
+ remove: function() {
+ return this.each(function(i, el) {
+ var $el = $(el);
+
+ $.each(contexts, function(i, c) {
+ var ndx = waypointIndex($el, c);
+
+ if (ndx >= 0) {
+ c.waypoints.splice(ndx, 1);
+ }
+ });
+ });
+ },
+
+ /*
+ jQuery.fn.waypoint('destroy')
+
+ Passing the string 'destroy' to .waypoint will unbind all
waypoint.reached
+ event handlers on those elements and unregisters them as
waypoints.
+ */
+ destroy: function() {
+ return this.unbind(eventName)[wp]('remove');
+ }
+ },
+
+ /*
+ Methods used by the jQuery object extension.
+ */
+ jQMethods = {
+
+ /*
+ jQuery.waypoints('refresh')
+
+ This will force a recalculation of each waypoint’s trigger
point based on
+ its offset option and context. This is called automatically
whenever the window
+ (or other defined context) is resized, new waypoints are added,
or a waypoint’s
+ options are modified. If your project is changing the DOM or
page layout without
+ doing one of these things, you may want to manually call this
refresh.
+ */
+ refresh: function() {
+ $.each(contexts, function(i, c) {
+ var isWin = $.isWindow(c.element[0]),
+ contextOffset = isWin ? 0 :
c.element.offset().top,
+ contextHeight = isWin ?
$[wps]('viewportHeight') : c.element.height(),
+ contextScroll = isWin ? 0 :
c.element.scrollTop();
+
+ $.each(c.waypoints, function(j, o) {
+ /* $.each isn't safe from element removal
due to triggerOnce.
+ Should rewrite the loop but this is way
easier. */
+ if (!o) return;
+
+ // Adjustment is just the offset if
it's a px value
+ var adjustment = o.options.offset,
+ oldOffset = o.offset;
+
+ // Set adjustment to the return value
if offset is a function.
+ if (typeof o.options.offset ===
"function") {
+ adjustment =
o.options.offset.apply(o.element);
+ }
+ // Calculate the adjustment if offset
is a percentage.
+ else if (typeof o.options.offset ===
"string") {
+ var amount =
parseFloat(o.options.offset);
+ adjustment =
o.options.offset.indexOf("%") ?
+ Math.ceil(contextHeight
* (amount / 100)) : amount;
+ }
+
+ /*
+ Set the element offset to the window
scroll offset, less
+ all our adjustments.
+ */
+ o.offset = o.element.offset().top -
contextOffset
+ + contextScroll - adjustment;
+
+ /*
+ An element offset change across the
current scroll point triggers
+ the event, just as if we scrolled past
it unless prevented by an
+ optional flag.
+ */
+ if (o.options.onlyOnScroll) return;
+
+ if (oldOffset !== null && c.oldScroll >
oldOffset && c.oldScroll <= o.offset) {
+ triggerWaypoint(o, ['up']);
+ }
+ else if (oldOffset !== null &&
c.oldScroll < oldOffset && c.oldScroll >= o.offset) {
+ triggerWaypoint(o, ['down']);
+ }
+ /* For new waypoints added after load,
check that down should have
+ already been triggered */
+ else if (!oldOffset && contextScroll >
o.offset) {
+ triggerWaypoint(o, ['down']);
+ }
+ });
+
+ // Keep waypoints sorted by offset value.
+ c.waypoints.sort(function(a, b) {
+ return a.offset - b.offset;
+ });
+ });
+ },
+
+
+ /*
+ jQuery.waypoints('viewportHeight')
+
+ This will return the height of the viewport, adjusting for
inconsistencies
+ that come with calling $(window).height() in iOS. Recommended
for use
+ within any offset functions.
+ */
+ viewportHeight: function() {
+ return (window.innerHeight ? window.innerHeight :
$w.height());
+ },
+
+
+ /*
+ jQuery.waypoints()
+
+ This will return a jQuery object with a collection of all
registered waypoint
+ elements.
+
+ $('.post').waypoint();
+ $('.ad-unit').waypoint(function(event, direction) {
+ // Passed an ad unit
+ });
+ console.log($.waypoints());
+
+ The example above would log a jQuery object containing all
.post and .ad-unit
+ elements.
+ */
+ aggregate: function() {
+ var points = $();
+ $.each(contexts, function(i, c) {
+ $.each(c.waypoints, function(i, e) {
+ points = points.add(e.element);
+ });
+ });
+ return points;
+ }
+ };
+
+
+ /*
+ fn extension. Delegates to appropriate method.
+ */
+ $.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 );
+ }
+ };
+
+
+ /*
+ The default options object that is extended when calling .waypoint. It
has the
+ following properties:
+
+ context
+ string | element | jQuery*
+ default: window
+ The context defines which scrollable element the waypoint
belongs to and acts
+ within. The default, window, means the waypoint offset is
calculated with relation
+ to the whole viewport. You can set this to another element to
use the waypoints
+ within that element. Accepts a selector string, *but if you
use jQuery 1.6+ it
+ also accepts a raw HTML element or jQuery object.
+
+ continuous
+ boolean
+ default: true
+ If true, and multiple waypoints are triggered in one scroll,
this waypoint will
+ trigger even if it is not the last waypoint reached. If false,
it will only
+ trigger if it is the last waypoint.
+
+ handler
+ function
+ default: undefined
+ An alternative way to bind functions to the waypoint, without
using the function
+ as the first argument to the waypoint function.
+
+ offset
+ number | string | function
+ default: 0
+ Determines how far the top of the element must be from the top
of the browser
+ window to trigger a waypoint. It can be a number, which is
taken as a number
+ of pixels, a string representing a percentage of the viewport
height, or a
+ function that will return a number of pixels.
+
+ onlyOnScroll
+ boolean
+ default: false
+ If true, this waypoint will not trigger if an offset change
during a refresh
+ causes it to pass the current scroll point.
+
+ triggerOnce
+ boolean
+ default: false
+ If true, the waypoint will be destroyed when triggered.
+
+ An offset of 250 would trigger the waypoint when the top of the element
is 250px
+ from the top of the viewport. Negative values for any offset work as
you might
+ expect. A value of -100 would trigger the waypoint when the element is
100px above
+ the top of the window.
+
+ offset: '100%'
+
+ A string percentage will determine the pixel offset based on the height
of the
+ window. When resizing the window, this offset will automatically be
recalculated
+ without needing to call $.waypoints('refresh').
+
+ // The bottom of the element is in view
+ offset: function() {
+ return $.waypoints('viewportHeight') - $(this).outerHeight();
+ }
+
+ Offset can take a function, which must return a number of pixels from
the top of
+ the window. The this value will always refer to the raw HTML element of
the
+ waypoint. As with % values, functions are recalculated automatically
when the
+ window resizes. For more on recalculating offsets, see
$.waypoints('refresh').
+
+ An offset value of 'bottom-in-view' will act as an alias for the
function in the
+ example above, as this is a common usage.
+
+ offset: 'bottom-in-view'
+
+ You can see this alias in use on the Scroll Analytics example page.
+
+ The triggerOnce flag, if true, will destroy the waypoint after the
first trigger.
+ This is just a shortcut for calling .waypoint('destroy') within the
waypoint
+ handler. This is useful in situations such as scroll analytics, where
you only
+ want to record an event once for each page visit.
+
+ The context option lets you use Waypoints within an element other than
the window.
+ You can define the context with a selector string and the waypoint will
act within
+ the nearest ancestor that matches this selector.
+
+ $('.something-scrollable .waypoint').waypoint({
+ context: '.something-scrollable'
+ });
+
+ You can see this in action on the Dial Controls example.
+
+ The handler option gives authors an alternative way to bind functions
when
+ creating a waypoint. In place of:
+
+ $('.item').waypoint(function(event, direction) {
+ // make things happen
+ });
+
+ You may instead write:
+
+ $('.item').waypoint({
+ handler: function(event, direction) {
+ // make things happen
+ }
+ });
+
+ */
+ $.fn[wp].defaults = {
+ continuous: true,
+ offset: 0,
+ triggerOnce: false,
+ context: window
+ };
+
+
+
+
+
+ /*
+ jQuery object extension. Delegates to appropriate methods above.
+ */
+ $[wps] = function(method) {
+ if (jQMethods[method]) {
+ return jQMethods[method].apply(this);
+ }
+ else {
+ return jQMethods['aggregate']();
+ }
+ };
+
+
+ /*
+ $.waypoints.settings
+
+ Settings object that determines some of the plugin’s behavior.
+
+ resizeThrottle
+ number
+ default: 200
+ For performance reasons, the refresh performed during resizes is
+ throttled. This value is the rate-limit in milliseconds between
resize
+ refreshes. For more information on throttling, check out Ben
Alman’s
+ throttle / debounce plugin.
+ http://benalman.com/projects/jquery-throttle-debounce-plugin/
+
+ scrollThrottle
+ number
+ default: 100
+ For performance reasons, checking for any crossed waypoints
during a
+ scroll event is throttled. This value is the rate-limit in
milliseconds
+ between scroll checks. For more information on throttling,
check out Ben
+ Alman’s throttle / debounce plugin.
+ http://benalman.com/projects/jquery-throttle-debounce-plugin/
+ */
+ $[wps].settings = {
+ resizeThrottle: 200,
+ scrollThrottle: 100
+ };
+
+ $w.load(function() {
+ // Calculate everything once on load.
+ $[wps]('refresh');
+ });
+})(jQuery, 'waypoint', 'waypoints', window);
Property changes on:
trunk/extensions/PageTriage/modules/external/jquery.waypoints.js
___________________________________________________________________
Added: svn:eol-style
+ native
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs