ScrollSpy

ScrollSpy is a MooTools plugin that listens to the page’s scroll position and fires events based upon where the user is on the page.

Download Debut Article Example Usage

Plugin Code (Version 1.0)

/* scroll spy plugin / class */
var ScrollSpy = new Class({
	
	/* implements */
	Implements: [Options,Events],

	/* options */
	options: {
		min: 0,
		mode: 'vertical',
		max: 0,
		container: window,
		onEnter: $empty,
		onLeave: $empty,
		onTick: $empty
	},
	
	/* initialization */
	initialize: function(options) {
		/* set options */
		this.setOptions(options);
		this.container = $(this.options.container);
		this.enters = this.leaves = 0;
		this.max = this.options.max;
		
		/* fix max */
		if(this.max == 0) 
		{ 
			var ss = this.container.getScrollSize();
			this.max = this.options.mode == 'vertical' ? ss.y : ss.x;
		}
		/* make it happen */
		this.addListener();
	},
	
	/* a method that does whatever you want */
	addListener: function() {
		/* state trackers */
		this.inside = false;
		this.container.addEvent('scroll',function() {
			/* if it has reached the level */
			var position = this.container.getScroll();
			var xy = this.options.mode == 'vertical' ? position.y : position.x;
			/* if we reach the minimum and are still below the max... */
			if(xy >= this.options.min && xy <= this.max) {
					/* trigger Enter event if necessary */
					if(!this.inside) {
						/* record as inside */
						this.inside = true;
						this.enters++;
						/* fire enter event */
						this.fireEvent('enter',[position,this.enters]);
					}
					/* trigger the "tick", always */
					this.fireEvent('tick',[position,this.inside,this.enters,this.leaves]);
			}
			else {
				/* trigger leave */
				if(this.inside) 
				{
					this.inside = false;
					this.leaves++;
					this.fireEvent('leave',[position,this.leaves]);
				}
			}
		}.bind(this));
	}
});

/* usage */
window.addEvent('domready',function() {
	/* smooth */
	new SmoothScroll({duration:500});
	
	/* link management */
	$('gototop').set('opacity','0').setStyle('display','block');
	
	/* scrollspy instance */
	var ss = new ScrollSpy({
		min: 200,
		onEnter: function(position,enters) {
			if(console) { console.log('Entered [' + enters + '] at: ' + position.x + ' / ' + position.y); }
			$('gototop').fade('in');
		},
		onLeave: function(position,leaves) {
			if(console) { console.log('Left [' + leaves + '] at: ' + position.x + ' / ' + position.y); }
			$('gototop').fade('out');
		},
		onTick: function(position,state,enters,leaves) {
			if(console) { console.log('Tick  [' + enters + ', ' + leaves + '] at: ' + position.x + ' / ' + position.y); }
		},
		container: window
	});
});

Options & Events

  • min: (defaults to 0) The minimum value of the X or Y coordinate, depending on mode.
  • max: (defaults to 0) The maximum value of the X or Y coordinate, depending on mode.
  • mode: (defaults to 'vertical') Defines whether to listen to X or Y scrolling.
  • container: (defaults to window) The element whose scrolling to listen to.

Events for ScrollSpy include:

  • Tick: Fires on each scroll event within the min and max parameters. Receives as parameters:
    • position: an object with the current X and Y position.
    • inside: a Boolean value for whether or not the user is within the min and max parameters
    • enters: the number of times the min / max has been entered.
    • leaves: the number of times the min / max has been left.
  • Enter: Fires every time the user enters the min / max zone.
    • position: an object with the current X and Y position.
    • enters: the number of times the min / max has been entered.
  • Leave: Fires every time the user leaves the min / max zone.
    • position: an object with the current X and Y position.
    • leaves: the number of times the min / max has been left.

Code Revisions & Bug Fixes

None.

Comments

  1. I have this plugin at a joomla based site but the issue is that the Top link is always invisible irrespective of the scroll position. Could you please let me know how this can be fixed.

  2. Wow i just used this script to move a panel -left when you scroll right. My problem that the panel needed to be fixed for vertical movement but absolute positioned for horizontal movement. This script was the fix!!!!

    David you could write a moo-plugin that allows new css types: position-x: absolute; position-y: fixed through javascript. Now that would be cool!

  3. I really like this and have started to try to use it more often. I see a problem in IE, though, where the ‘top of page’ link doesn’t appear in the bottom corner, but rather in the upper left and only when you scroll to the bottom then manually scroll up to the top. Is there a ‘fix’ to make the link work correctly in IE? Or have I missed something in the css?

    Great app, really like it.

  4. Chris: IE is rubbish when it comes to fixed positioning. Try to combine my ScrollSpy class with Element.Pin: http://mootools.net/docs/more/Element/Element.Pin

  5. Jonathan Stuebe October 11, 2009

    Is there anyway you could write this for jquery?

  6. […] Implements array and you can fire events anywhere you want — these events are extremely helpful. ScrollSpy and many other popular MooTools plugins would be nothing without events. And think of DOM elements […]

Be Heard

Tip: Wrap your code in <pre> tags or link to a GitHub Gist!

Use Code Editor