-
Notifications
You must be signed in to change notification settings - Fork 8
/
infiniscroll.js
121 lines (96 loc) · 3.76 KB
/
infiniscroll.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
114
115
116
117
118
119
120
121
/*
* Infiniscroll v1.0
* https://github.com/gilbitron/Infiniscroll
*
* Copyright 2014, Gilbert Pellegrom
* Free to use and abuse under the MIT license.
* http://opensource.org/licenses/MIT
*/
;(function($, window, document, undefined){
var pluginName = 'infiniscroll',
defaults = {
navSelector: '.pagination', // Selector for your static naivgation (this will be hidden)
nextSelector: '.pagination a.next', // Selector for the NEXT link (e.g. to page 2)
loadingSelector: '.loading', // Selector for the loading element
pageFragment: '.content', // Selector for the content you want to extract from the response
scrollBuffer: 200, // The scroll amount in px before the bottom of the page that Infiniscroll should start to load the next page
scrollOnLoad: true, // Should the window scroll to the position of the newly loaded content (if the user is at the bottom of the page)
scrollOnLoadDistance: 200, // The distance to scroll down when new content is loaded,
scrollOnLoadSpeed: 500, // The speed to scroll down when new content is loaded
onInit: function(){}, // Callback after plugin has loaded
beforeContentLoaded: function(link){}, // Callback before new content is loaded
afterContentLoaded: function(html){} // Callback after new content has been loaded
};
function Infiniscroll(element, options){
this.el = element;
this.$el = $(this.el);
this.options = $.extend({}, defaults, options);
this._isLoading = false;
this._nextLink = null;
this.init();
}
Infiniscroll.prototype = {
init: function(){
var $this = this;
// Hide the pagination container
$(this.options.navSelector).hide();
// Setup the scroll event listener
$(window).on('scroll', function(){
$this.doScroll.apply($this);
});
this.options.onInit.call(this);
},
doScroll: function(){
// Only load one page at a time
if(this._isLoading) return;
// Do we need to load the next page?
if($(window).scrollTop() >= ($(document).height() - $(window).height() - this.options.scrollBuffer)){
this._isLoading = true;
// Get the next page link
if(!this._nextLink){
this._nextLink = $(this.options.nextSelector);
}
if(this._nextLink.attr('href')){
this.options.beforeContentLoaded.call(this, this._nextLink);
$(this.options.loadingSelector).show();
// Setup "iscroll" for use in the load() callback
var iscroll = this,
url = this._nextLink.attr('href');
// Add pageFragment to URL if required
if(this.options.pageFragment)
url += ' '+ this.options.pageFragment;
// Load the next page into an off-DOM div
$('<div/>').load(url, function(){
var html = $(this).children(),
shouldScroll = false;
// If user is waiting at bottom of page?
if(iscroll.options.scrollOnLoad && $(window).scrollTop() === $(document).height() - $(window).height())
shouldScroll = true;
// Process new content
html.find(iscroll.options.navSelector).hide();
iscroll._nextLink = html.find(iscroll.options.nextSelector);
// Hide the loader
$(iscroll.options.loadingSelector).hide();
// Actually add our new content to the container
html.appendTo(iscroll.el);
// Scroll to the new content
if(shouldScroll){
$('html, body').animate({
scrollTop: $(window).scrollTop() + iscroll.options.scrollOnLoadDistance
}, iscroll.options.scrollOnLoadSpeed);
}
iscroll._isLoading = false;
iscroll.options.afterContentLoaded.call(iscroll, html);
});
}
}
}
};
$.fn[pluginName] = function(options){
return this.each(function(){
if(!$.data(this, pluginName)){
$.data(this, pluginName, new Infiniscroll(this, options));
}
});
};
})(jQuery, window, document);