forked from mvlandys/jquery.dragscrollable
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dragscrollable.js
148 lines (136 loc) · 5.68 KB
/
dragscrollable.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
* jQuery dragscrollable Plugin
* version: 1.1 (31-May-2016)
* Copyright (c) 2009 Miquel Herrera
* Modified 2016 by Alexander Steinhöfer
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*/
;(function($){ // secure $ jQuery alias
/**
* Adds the ability to manage elements scroll by dragging
* one or more of its descendant elements. Options parameter
* allow to specifically select which inner elements will
* respond to the drag events.
*
* options properties:
* ------------------------------------------------------------------------
* dragSelector | jquery selector to apply to each wrapped element
* | to find which will be the dragging elements.
* | Defaults to '>:first' which is the first child of
* | scrollable element
* ------------------------------------------------------------------------
* acceptPropagatedEvent| Will the dragging element accept propagated
* | events? default is yes, a propagated mouse event
* | on a inner element will be accepted and processed.
* | If set to false, only events originated on the
* | draggable elements will be processed.
* ------------------------------------------------------------------------
* preventDefault | Prevents the event to propagate further effectivey
* | dissabling other default actions. Defaults to true
* ------------------------------------------------------------------------
*
* usage examples:
*
* To add the scroll by drag to the element id=viewport when dragging its
* first child accepting any propagated events
* $('#viewport').dragscrollable();
*
* To add the scroll by drag ability to any element div of class viewport
* when dragging its first descendant of class dragMe responding only to
* evcents originated on the '.dragMe' elements.
* $('div.viewport').dragscrollable({dragSelector:'.dragMe:first',
* acceptPropagatedEvent: false});
*
* Notice that some 'viewports' could be nested within others but events
* would not interfere as acceptPropagatedEvent is set to false.
*
*/
$.fn.dragscrollable = function( options ){
var settings = $.extend({
dragSelector:'>:first',
acceptPropagatedEvent: true,
preventDefault: true,
// Hovav:
allowY: true
}, options || {});
var dragscroll= {
startDrag: function(event, x, y) {
// Initial coordinates will be the last when dragging
event.data.lastCoord = {left: x, top: y};
},
doDrag: function(event, x, y) {
// How much did the mouse move?
var delta = {
left: (x - event.data.lastCoord.left),
top: ((settings.allowY) ? y - event.data.lastCoord.top : 0)
};
// Set the scroll position relative to what ever the scroll is now
event.data.scrollable.scrollLeft(event.data.scrollable.scrollLeft() - delta.left);
event.data.scrollable.scrollTop(event.data.scrollable.scrollTop() - delta.top);
// Save where the cursor is
event.data.lastCoord={ left: x, top: y };
},
/* ==========================================================
Touch */
touchStartHandler: function(event) {
var touch = event.originalEvent.touches[0];
dragscroll.startDrag(event, touch.pageX, touch.pageY);
$.event.add( document, "touchend", dragscroll.touchEndHandler, event.data );
$.event.add( document, "touchmove", dragscroll.touchMoveHandler, event.data );
},
touchMoveHandler: function(event) {
var touch = event.originalEvent.touches[0];
dragscroll.doDrag(event, touch.pageX, touch.pageY);
},
touchEndHandler: function(event) {
$.event.remove( document, "touchmove", dragscroll.mouseMoveHandler);
$.event.remove( document, "touchend", dragscroll.mouseUpHandler);
},
/* ==========================================================
Mouse */
mouseDownHandler : function(event) {
// mousedown, left click, check propagation
if (event.which != 1 || (!event.data.acceptPropagatedEvent && event.target != this)){
return false;
}
dragscroll.startDrag(event, event.clientX, event.clientY);
$.event.add( document, "mouseup", dragscroll.mouseUpHandler, event.data );
$.event.add( document, "mousemove", dragscroll.mouseMoveHandler, event.data );
if (event.data.preventDefault) {
event.preventDefault();
return false;
}
},
mouseMoveHandler : function(event) { // User is dragging
dragscroll.doDrag(event, event.clientX, event.clientY);
if (event.data.preventDefault) {
event.preventDefault();
return false;
}
},
mouseUpHandler : function(event) { // Stop scrolling
$.event.remove( document, "mousemove", dragscroll.mouseMoveHandler);
$.event.remove( document, "mouseup", dragscroll.mouseUpHandler);
if (event.data.preventDefault) {
event.preventDefault();
return false;
}
}
}
// set up the initial events
this.each(function() {
// closure object data for each scrollable element
var data = {
scrollable : $(this),
acceptPropagatedEvent : settings.acceptPropagatedEvent,
preventDefault : settings.preventDefault
};
// Set mouse initiating event on the desired descendant
$(this).find(settings.dragSelector).bind('mousedown', data, dragscroll.mouseDownHandler);
$(this).find(settings.dragSelector).bind('touchstart', data, dragscroll.touchStartHandler);
});
}; //end plugin dragscrollable
})( jQuery ); // confine scope