-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathjquery.scrollcallback.js
106 lines (97 loc) · 2.98 KB
/
jquery.scrollcallback.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
/**
* ScrollCallback
* Copyright (c) 2015 Pavel Khoroshkov. Licensed under the [MIT license](https://github.com/pgooood/scrollcallback/blob/master/LICENSE).
* @author Pavel Khoroshkov aka pgood
* @link https://github.com/pgooood/scrollcallback
*/
(function($){
$.fn.scrollcallback = function(v){
var options = {
context:window
};
switch(typeof(v)){
case 'function':
options = $.extend(options,{inHandler:v});
break;
case 'object':
if(v.inHandler || v.outHandler){
options = $.extend(options,v);
break;
};
default:
return false;
};
return new scrollcallback(this,options.inHandler,options.outHandler,options.context);
};
function scrollcallback(element,inHandler,outHandler,context){
var ar = []
,$context = context ? $(context) : $(window)
,lastScrollPos = {left:0,top:0}
,direction = function(){
var res
,scrollLeft = $context.scrollLeft()
,scrollTop = $context.scrollTop();
switch(true){
case scrollTop > lastScrollPos.top:
res = 'down'; break;
case scrollTop < lastScrollPos.top:
res = 'up'; break;
case scrollLeft > lastScrollPos.left:
res = 'right'; break;
case scrollLeft < lastScrollPos.left:
res = 'left'; break;
};
lastScrollPos.left = scrollLeft;
lastScrollPos.top = scrollTop;
return res;
};
$(element).each(function(){
ar.push(new spoint(this,inHandler,outHandler,context));
});
$context.scroll(function(){
var d = direction();
for(var i = 0,l = ar.length; i < l; i++)
ar[i].handler(d);
}).scroll();
};
function spoint(e,inHandler,outHandler,context){
this.charged = false;
this.$e = $(e);
this.$context = context && !$.isWindow(context) ? this.$e.parents(context) : $(window)
this.onIn = function(direction){
if(!this.charged && typeof(inHandler) == 'function')
inHandler(this.$e.get(0),direction);
this.charged = true;
};
this.onOut = function(direction){
if(this.charged && typeof(outHandler) == 'function')
outHandler(this.$e.get(0),direction);
this.charged = false;
};
};
spoint.prototype.offset = function($e){
var res = {left:0,top:0},offset;
do{
offset = $e.offset();
res.left += offset.left;
res.top += offset.top;
$e = $e.offsetParent();
}while(!$e.prop('tagName').toLowerCase() == 'body');
return res;
};
spoint.prototype.visible = function(){
var $c = this.$context,offset = this.offset(this.$e);
if(!$.isWindow(this.$context.get(0))){
var offsetContext = this.offset(this.$context);
offset.left -= offsetContext.left - this.$context.scrollLeft();
offset.top -= offsetContext.top - this.$context.scrollTop();
};
return ($c.scrollLeft() + $c.width() > offset.left && $c.scrollLeft() < offset.left + this.$e.width())
&& ($c.scrollTop() + $c.height() > offset.top && $c.scrollTop() < offset.top + this.$e.height());
};
spoint.prototype.handler = function(direction){
if(this.visible())
this.onIn(direction);
else this.onOut(direction);
};
}(jQuery));