Skip to content

Commit 14bacc4

Browse files
committed
reworked binding and unbinding
1 parent 3b17638 commit 14bacc4

File tree

11 files changed

+135
-47
lines changed

11 files changed

+135
-47
lines changed

doc/methods.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jQuery.ias().bind();
1111

1212
### destroy
1313

14-
Alias of [unbind](methods.html#unbind) method.
14+
Unbinds and destroys instance.
1515

1616
### extension
1717

src/callbacks.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,16 @@ var IASCallbacks = function () {
2323
var context = args[0],
2424
deferred = args[1],
2525
callbackArguments = args[2];
26+
2627
this.isFiring = true;
2728

2829
for (var i = 0, l = this.list.length; i < l; i++) {
29-
if (false === this.list[i].fn.apply(context, callbackArguments)) {
30-
deferred.reject();
30+
if (this.list[i] != undefined) {
31+
if (false === this.list[i].fn.apply(context, callbackArguments)) {
32+
deferred.reject();
3133

32-
break;
34+
break;
35+
}
3336
}
3437
}
3538

src/extension/history.js

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,11 @@ var IASHistoryExtension = function (options) {
2525
* @param url
2626
*/
2727
this.onPageChange = function (pageNum, scrollOffset, url) {
28-
var state = {};
29-
3028
if (!window.history || !window.history.replaceState) {
3129
return;
3230
}
3331

34-
state = history.state;
32+
var state = history.state;
3533

3634
history.replaceState(state, document.title, url);
3735
};
@@ -55,6 +53,17 @@ var IASHistoryExtension = function (options) {
5553
}
5654
};
5755

56+
this.onReady = function () {
57+
var currentScrollOffset = this.ias.getCurrentScrollOffset(this.ias.$scrollContainer),
58+
firstItemScrollThreshold = this.getScrollThresholdFirstItem();
59+
60+
currentScrollOffset -= this.ias.$scrollContainer.height();
61+
62+
if (currentScrollOffset <= firstItemScrollThreshold) {
63+
this.prev();
64+
}
65+
};
66+
5867
/**
5968
* Returns the url for the next page
6069
*
@@ -150,20 +159,19 @@ IASHistoryExtension.prototype.initialize = function (ias) {
150159
* @param ias
151160
*/
152161
IASHistoryExtension.prototype.bind = function (ias) {
153-
var self = this;
154-
155162
ias.on('pageChange', jQuery.proxy(this.onPageChange, this));
156163
ias.on('scroll', jQuery.proxy(this.onScroll, this));
157-
ias.on('ready', function () {
158-
var currentScrollOffset = ias.getCurrentScrollOffset(ias.$scrollContainer),
159-
firstItemScrollThreshold = self.getScrollThresholdFirstItem();
160-
161-
currentScrollOffset -= ias.$scrollContainer.height();
164+
ias.on('ready', jQuery.proxy(this.onReady, this));
165+
};
162166

163-
if (currentScrollOffset <= firstItemScrollThreshold) {
164-
self.prev();
165-
}
166-
});
167+
/**
168+
* @public
169+
* @param {object} ias
170+
*/
171+
IASHistoryExtension.prototype.unbind = function(ias) {
172+
ias.off('pageChange', this.onPageChange);
173+
ias.off('scroll', this.onScroll);
174+
ias.off('ready', this.onReady);
167175
};
168176

169177
/**
@@ -180,7 +188,7 @@ IASHistoryExtension.prototype.prev = function () {
180188
return false;
181189
}
182190

183-
ias.unbind();
191+
ias.pause();
184192

185193
var promise = ias.fire('prev', [url]);
186194

@@ -189,7 +197,7 @@ IASHistoryExtension.prototype.prev = function () {
189197
self.renderBefore(items, function () {
190198
self.prevUrl = self.getPrevUrl(data);
191199

192-
ias.bind();
200+
ias.resume();
193201

194202
if (self.prevUrl) {
195203
self.prev();
@@ -199,7 +207,7 @@ IASHistoryExtension.prototype.prev = function () {
199207
});
200208

201209
promise.fail(function () {
202-
ias.bind();
210+
ias.resume();
203211
});
204212

205213
return true;

src/extension/noneleft.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ IASNoneLeftExtension.prototype.bind = function(ias) {
3838
ias.on('noneLeft', jQuery.proxy(this.showNoneLeft, this));
3939
};
4040

41+
/**
42+
* @public
43+
* @param {object} ias
44+
*/
45+
IASNoneLeftExtension.prototype.unbind = function(ias) {
46+
ias.off('noneLeft', this.showNoneLeft);
47+
};
48+
4149
/**
4250
* @public
4351
*/

src/extension/paging.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,19 @@ IASPagingExtension.prototype.bind = function(ias) {
118118
ias.on('scroll', jQuery.proxy(this.onScroll, this), this.priority);
119119
};
120120

121+
/**
122+
* @public
123+
* @param {object} ias
124+
*/
125+
IASPagingExtension.prototype.unbind = function(ias) {
126+
try {
127+
ias.off('prev', this.onPrev);
128+
} catch (exception) {}
129+
130+
ias.off('next', this.onNext);
131+
ias.off('scroll', this.onScroll);
132+
};
133+
121134
/**
122135
* Returns current page number based on scroll offset
123136
*

src/extension/spinner.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,24 @@ IASSpinnerExtension.prototype.bind = function(ias) {
9090
this.ias = ias;
9191

9292
ias.on('next', jQuery.proxy(this.showSpinner, this));
93+
ias.on('render', jQuery.proxy(this.removeSpinner, this));
9394

9495
try {
9596
ias.on('prev', jQuery.proxy(this.showSpinnerBefore, this));
9697
} catch (exception) {}
98+
};
9799

98-
ias.on('render', jQuery.proxy(this.removeSpinner, this));
100+
/**
101+
* @public
102+
* @param {object} ias
103+
*/
104+
IASSpinnerExtension.prototype.unbind = function(ias) {
105+
ias.off('next', this.showSpinner);
106+
ias.off('render', this.removeSpinner);
107+
108+
try {
109+
ias.off('prev', this.showSpinnerBefore);
110+
} catch (exception) {}
99111
};
100112

101113
/**

src/extension/trigger.js

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ var IASTriggerExtension = function(options) {
5858
return false;
5959
};
6060

61+
this.onRendered = function() {
62+
this.enabled = true;
63+
};
64+
6165
/**
6266
* @param clickCallback
6367
* @returns {*|jQuery}
@@ -88,20 +92,33 @@ IASTriggerExtension.prototype.bind = function(ias) {
8892

8993
this.ias = ias;
9094

95+
ias.on('next', jQuery.proxy(this.showTriggerNext, this), this.priority);
96+
ias.on('rendered', jQuery.proxy(this.onRendered, this), this.priority);
97+
9198
try {
9299
ias.on('prev', jQuery.proxy(this.showTriggerPrev, this), this.priority);
93100
} catch (exception) {}
101+
};
94102

95-
ias.on('next', jQuery.proxy(this.showTriggerNext, this), this.priority);
96-
ias.on('rendered', function () { self.enabled = true; }, this.priority);
103+
/**
104+
* @public
105+
* @param {object} ias
106+
*/
107+
IASTriggerExtension.prototype.unbind = function(ias) {
108+
ias.off('next', this.showTriggerNext);
109+
ias.off('rendered', this.onRendered);
110+
111+
try {
112+
ias.off('prev', this.showTriggerPrev);
113+
} catch (exception) {}
97114
};
98115

99116
/**
100117
* @public
101118
*/
102119
IASTriggerExtension.prototype.next = function() {
103120
this.enabled = false;
104-
this.ias.unbind();
121+
this.ias.pause();
105122

106123
if (this.$triggerNext) {
107124
this.$triggerNext.remove();
@@ -116,7 +133,7 @@ IASTriggerExtension.prototype.next = function() {
116133
*/
117134
IASTriggerExtension.prototype.prev = function() {
118135
this.enabled = false;
119-
this.ias.unbind();
136+
this.ias.pause();
120137

121138
if (this.$triggerPrev) {
122139
this.$triggerPrev.remove();

src/jquery-ias.js

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
this.negativeMargin = options.negativeMargin;
2929
this.nextUrl = null;
3030
this.isBound = false;
31+
this.isPaused = false;
3132
this.listeners = {
3233
next: new IASCallbacks(),
3334
load: new IASCallbacks(),
@@ -48,15 +49,15 @@
4849
* @private
4950
*/
5051
this.scrollHandler = function() {
51-
var currentScrollOffset = this.getCurrentScrollOffset(this.$scrollContainer),
52-
scrollThreshold = this.getScrollThreshold()
53-
;
54-
5552
// the throttle method can call the scrollHandler even thought we have called unbind()
56-
if (!this.isBound) {
53+
if (!this.isBound || this.isPaused) {
5754
return;
5855
}
5956

57+
var currentScrollOffset = this.getCurrentScrollOffset(this.$scrollContainer),
58+
scrollThreshold = this.getScrollThreshold()
59+
;
60+
6061
// invalid scrollThreshold. The DOM might not have loaded yet...
6162
if (UNDETERMINED_SCROLLOFFSET == scrollThreshold) {
6263
return;
@@ -320,6 +321,28 @@
320321
return this.listeners[event].fireWith(this, args);
321322
};
322323

324+
/**
325+
* Pauses the scroll handler
326+
*
327+
* Note: internal use only, if you need to pause IAS use `unbind` method.
328+
*
329+
* @private
330+
*/
331+
this.pause = function() {
332+
this.isPaused = true;
333+
};
334+
335+
/**
336+
* Resumes the scroll handler
337+
*
338+
* Note: internal use only, if you need to resume IAS use `bind` method.
339+
*
340+
* @private
341+
*/
342+
this.resume = function() {
343+
this.isPaused = false;
344+
};
345+
323346
return this;
324347
};
325348

@@ -337,10 +360,6 @@
337360
this.hidePagination();
338361
this.bind();
339362

340-
for (var i = 0, l = this.extensions.length; i < l; i++) {
341-
this.extensions[i].bind(this);
342-
}
343-
344363
this.fire('ready');
345364

346365
this.nextUrl = this.getNextUrl();
@@ -375,7 +394,12 @@
375394

376395
this.$scrollContainer.on('scroll', $.proxy(this.throttle(this.scrollHandler, 150), this));
377396

397+
for (var i = 0, l = this.extensions.length; i < l; i++) {
398+
this.extensions[i].bind(this);
399+
}
400+
378401
this.isBound = true;
402+
this.resume();
379403
};
380404

381405
/**
@@ -390,6 +414,13 @@
390414

391415
this.$scrollContainer.off('scroll', this.scrollHandler);
392416

417+
// notify extensions about unbinding
418+
for (var i = 0, l = this.extensions.length; i < l; i++) {
419+
if (typeof this.extensions[i]['unbind'] != 'undefined') {
420+
this.extensions[i].unbind(this);
421+
}
422+
}
423+
393424
this.isBound = false;
394425
};
395426

@@ -474,13 +505,13 @@
474505
var url = this.nextUrl,
475506
self = this;
476507

477-
this.unbind();
508+
this.pause();
478509

479510
if (!url) {
480511
this.fire('noneLeft', [this.getLastItem()]);
481512
this.listeners['noneLeft'].disable(); // disable it so it only fires once
482513

483-
self.bind();
514+
self.resume();
484515

485516
return false;
486517
}
@@ -492,13 +523,13 @@
492523
self.render(items, function() {
493524
self.nextUrl = self.getNextUrl(data);
494525

495-
self.bind();
526+
self.resume();
496527
});
497528
});
498529
});
499530

500531
promise.fail(function() {
501-
self.bind();
532+
self.resume();
502533
});
503534

504535
return true;
@@ -520,6 +551,8 @@
520551

521552
this.extensions.push(extension);
522553

554+
this.reinitialize();
555+
523556
return this;
524557
};
525558

test/03-extensions-test.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ describe("IAS", function () {
5151
};
5252

5353
jQuery.ias().extension(new anExtension());
54-
jQuery.ias().initialize();
5554

5655
expect(spy1).toHaveBeenCalledOnce();
5756

@@ -84,7 +83,6 @@ describe("IAS", function () {
8483

8584
// now let's register the extension
8685
jQuery.ias().extension(new anExtension());
87-
jQuery.ias().initialize();
8886

8987
// this should now be possible and not throw an error
9088
jQuery.ias().on('test', function() {});

test/04-history-extension-test.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ describe("IAS", function () {
2323
prev: '.prev-posts a'
2424
}));
2525

26-
ias.initialize();
27-
2826
expect(ias.prev).toBeDefined();
2927
});
3028

0 commit comments

Comments
 (0)