@@ -19,6 +19,8 @@ $.widget( "ui.draggable", {
1919
2020 options : {
2121
22+ scrollSpeed : 20 ,
23+ scrollSensitivity :20 ,
2224 helper : false
2325
2426 } ,
@@ -47,43 +49,48 @@ $.widget( "ui.draggable", {
4749
4850 this . scrollParent = this . element . scrollParent ( ) ;
4951
52+ // Offset of scrollParent, used for auto-scrolling
53+ this . overflowOffset = { } ;
54+
55+ // Height of scrollParent, used for auto-scrolling
56+ this . overflowHeight = 0 ;
57+
58+ // Width of scrollParent, used for auto-scrolling
59+ this . overflowWidth = 0 ;
60+
5061 // Static position elements can"t be moved with top/left
5162 if ( this . element . css ( "position" ) === "static" ) {
5263 this . element . css ( "position" , "relative" ) ;
5364 }
54-
65+
5566 // Using proxy to avoid anon functions using self to pass "this" along
5667 this . element . bind ( "mousedown." + this . widgetName , $ . proxy ( this . _mouseDown , this ) ) ;
5768
5869 } ,
59-
70+
6071 _usingHelper : function ( ) {
6172 return ( this . options . helper === true || typeof this . options . helper === 'function' ) ;
6273 } ,
6374
6475 _setPosition : function ( ) {
6576
66- var left , top , position , cssPosition ;
77+ var left , top , position ,
78+ scrollTop = this . scrollParent . scrollTop ( ) ,
79+ scrollLeft = this . scrollParent . scrollLeft ( ) ;
6780
6881 // Helper is appended to body so offset of element is all that's needed
6982 if ( this . _usingHelper ( ) ) {
7083 return this . element . offset ( ) ;
7184 }
7285
73- cssPosition = this . dragEl . css ( "position" ) ; ;
74-
7586 // If fixed or absolute
76- if ( cssPosition !== "relative" ) {
87+ if ( this . cssPosition !== "relative" ) {
7788
7889 position = this . dragEl . position ( ) ;
7990
80- if ( cssPosition === "absolute" ) {
81- return position ;
82- }
83-
84- // Take into account scrollbar for fixed position
85- position . top = position . top - this . scrollParent . scrollTop ( ) ;
86- position . left = position . left - this . scrollParent . scrollLeft ( ) ;
91+ // Take into account scrollbar
92+ position . top = position . top - scrollTop ;
93+ position . left = position . left - scrollLeft
8794
8895 return position ;
8996
@@ -100,20 +107,22 @@ $.widget( "ui.draggable", {
100107
101108 return {
102109
103- left : left ,
104- top : top
110+ left : left - scrollLeft ,
111+ top : top - scrollTop
105112
106113 } ;
107114
108115 } ,
109116
110117 _mouseDown : function ( event ) {
111-
118+
112119 // Stop browser from highlighting, among other things
113120 event . preventDefault ( ) ;
114121
115122 // The actual dragging element, should always be a jQuery object
116123 this . dragEl = this . element ;
124+
125+ this . cssPosition = this . dragEl . css ( "position" ) ;
117126
118127 // Helper required, so clone, hide, and set reference
119128 if ( this . _usingHelper ( ) ) {
@@ -131,16 +140,16 @@ $.widget( "ui.draggable", {
131140 }
132141
133142 } else {
134-
143+
135144 this . dragEl = this . options . helper ( ) ;
136-
145+
137146 // If function was passed, it should return a DOMElement
138147 if ( typeof this . dragEl . nodeType !== 'number' ) {
139148 throw "Helper function must return a DOMElement" ;
140149 }
141-
150+
142151 this . dragEl = $ ( this . dragEl ) ;
143-
152+
144153 }
145154
146155 // Automatically make helper absolute
@@ -166,10 +175,15 @@ $.widget( "ui.draggable", {
166175 top : event . clientY
167176 } ;
168177
178+ // Cache the offset of scrollParent
179+ this . overflowOffset = this . scrollParent . offset ( ) ;
180+ this . overflowHeight = ( this . scrollParent [ 0 ] === document ) ? $ ( window ) . height ( ) : this . scrollParent . height ( ) ;
181+ this . overflowWidth = ( this . scrollParent [ 0 ] === document ) ? $ ( window ) . width ( ) : this . scrollParent . width ( ) ;
182+
169183 this . _trigger ( "start" , event ) ;
170184
171- $ ( document ) . bind ( "mousemove." + this . widgetName , $ . proxy ( this . _mouseMove , this ) ) ;
172- $ ( document ) . bind ( "mouseup." + this . widgetName , $ . proxy ( this . _mouseUp , this ) ) ;
185+ $ ( document ) . bind ( "mousemove." + this . widgetName , $ . proxy ( this . _mouseMove , this ) )
186+ . bind ( "mouseup." + this . widgetName , $ . proxy ( this . _mouseUp , this ) ) ;
173187
174188
175189 // Set the helper up by actual element
@@ -189,11 +203,11 @@ $.widget( "ui.draggable", {
189203 } ,
190204
191205 _mouseMove : function ( event ) {
192-
206+
193207 var leftDiff = event . clientX - this . startCoords . left ,
194- topDiff = event . clientY - this . startCoords . top ,
195- newLeft = leftDiff + this . startPosition . left ,
196- newTop = topDiff + this . startPosition . top ;
208+ topDiff = event . clientY - this . startCoords . top ,
209+ newLeft = leftDiff + this . startPosition . left ,
210+ newTop = topDiff + this . startPosition . top ;
197211
198212 this . position = {
199213 left : newLeft ,
@@ -213,18 +227,51 @@ $.widget( "ui.draggable", {
213227 this . offset = this . dragEl . offset ( ) ;
214228
215229 }
230+
231+ newLeft = this . position . left ;
232+ newTop = this . position . top ;
233+
234+ if ( this . cssPosition !== 'fixed' ) {
235+
236+ newLeft = newLeft + this . scrollParent . scrollLeft ( ) ;
237+ newTop = newTop + this . scrollParent . scrollTop ( ) ;
238+
239+ }
216240
217241 this . dragEl . css ( {
218242
219- left : this . position . left + "px" ,
220- top : this . position . top + "px"
243+ left : newLeft + "px" ,
244+ top : newTop + "px"
221245
222246 } ) ;
247+
248+ // Scroll the scrollParent, if needed
249+ this . _handleScrolling ( event ) ;
250+
251+ } ,
252+
253+ _handleScrolling : function ( event ) {
254+
255+ var doc = $ ( document ) ,
256+ scrollTop = doc . scrollTop ( ) ,
257+ scrollLeft = doc . scrollLeft ( ) ;
258+
259+ // Handle vertical scrolling
260+ if ( ( ( this . overflowHeight + scrollTop ) - event . pageY ) < this . options . scrollSensitivity ) {
261+ doc . scrollTop ( scrollTop + this . options . scrollSpeed ) ;
262+ }
263+
264+ // Handle horizontal scrolling
265+ if ( ( ( this . overflowWidth + scrollLeft ) - event . pageX ) < this . options . scrollSensitivity ) {
266+ doc . scrollLeft ( scrollLeft + this . options . scrollSpeed ) ;
267+ }
223268
224269 } ,
225270
226271 _mouseUp : function ( event ) {
227272
273+ var doc = $ ( document ) ;
274+
228275 this . _trigger ( "stop" , event ) ;
229276
230277 this . startCoords = { } ;
@@ -233,8 +280,8 @@ $.widget( "ui.draggable", {
233280 this . dragEl . remove ( ) ;
234281 }
235282
236- $ ( document ) . unbind ( "mousemove." + this . widgetName ) ;
237- $ ( document ) . unbind ( "mouseup." + this . widgetName ) ;
283+ doc . unbind ( "mousemove." + this . widgetName ) ;
284+ doc . unbind ( "mouseup." + this . widgetName ) ;
238285
239286 } ,
240287
0 commit comments