-
Notifications
You must be signed in to change notification settings - Fork 198
/
jquery.localScroll.js
113 lines (95 loc) · 3.46 KB
/
jquery.localScroll.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*!
* jQuery.localScroll
* Copyright (c) 2007 Ariel Flesler - aflesler<a>gmail<d>com | https://github.com/flesler
* Licensed under MIT
* http://flesler.blogspot.com/2007/10/jquerylocalscroll-10.html
* @author Ariel Flesler
* @version 2.0.0
*/
;(function(plugin) {
// AMD Support
if (typeof define === 'function' && define.amd) {
define(['jquery'], plugin);
} else {
plugin(jQuery);
}
}(function($) {
var URI = location.href.replace(/#.*/, ''); // local url without hash
var $localScroll = $.localScroll = function(settings) {
$('body').localScroll(settings);
};
// Many of these defaults, belong to jQuery.ScrollTo, check it's demo for an example of each option.
// @see http://demos.flesler.com/jquery/scrollTo/
// The defaults are public and can be overriden.
$localScroll.defaults = {
duration: 1000, // How long to animate.
axis: 'y', // Which of top and left should be modified.
event: 'click', // On which event to react.
stop: true, // Avoid queuing animations
target: window, // What to scroll (selector or element). The whole window by default.
autoscroll: true // If true, applies the scrolling at initial page load.
/*
lock: false, // ignore events if already animating
lazy: false, // if true, links can be added later, and will still work.
filter: null, // filter some anchors out of the matched elements.
hash: false, // if true, the hash of the selected link, will appear on the address bar.
onBefore: null // called before scrolling, "this" contains the settings and gets 3 arguments
*/
};
$.fn.localScroll = function(settings) {
settings = $.extend({}, $localScroll.defaults, settings);
if (settings.autoscroll && settings.hash && location.hash) {
if (settings.target) window.scrollTo(0, 0);
scroll(0, location, settings);
}
return settings.lazy ?
// use event delegation, more links can be added later.
this.on(settings.event, 'a,area', function(e) {
if (filter.call(this)) {
scroll(e, this, settings);
}
}) :
// bind concretely, to each matching link
this.find('a,area')
.filter(filter).bind(settings.event, function(e) {
scroll(e, this, settings);
}).end()
.end();
function filter() {// is this a link that points to an anchor and passes a possible filter ? href is checked to avoid a bug in FF.
return !!this.href && !!this.hash && this.href.replace(this.hash,'') === URI && (!settings.filter || $(this).is(settings.filter));
}
};
// Not needed anymore, kept for backwards compatibility
$localScroll.hash = function() {};
function scroll(e, link, settings) {
var id = link.hash.slice(1),
elem = document.getElementById(id) || document.getElementsByName(id)[0];
if (!elem) return;
if (e) e.preventDefault();
var $target = $(settings.target);
if (settings.lock && $target.is(':animated') ||
settings.onBefore && settings.onBefore(e, elem, $target) === false)
return;
if (settings.stop) {
$target.stop(true); // remove all its animations
}
if (settings.hash) {
var attr = elem.id === id ? 'id' : 'name',
$a = $('<a> </a>').attr(attr, id).css({
position:'absolute',
top: $(window).scrollTop(),
left: $(window).scrollLeft()
});
elem[attr] = '';
$('body').prepend($a);
location.hash = link.hash;
$a.remove();
elem[attr] = id;
}
$target
.scrollTo(elem, settings) // do scroll
.trigger('notify.serialScroll',[elem]); // notify serialScroll about this change
}
// AMD requirement
return $localScroll;
}));