DataTables Scroller Plugin White Space at top issue AND fix provided
DataTables Scroller Plugin White Space at top issue AND fix provided
khirakawa
Posts: 4Questions: 0Answers: 0
In the server-side scroller example here, a blank space is rendered when I scroll to down (just enough to trigger a fetch), then to the top very quickly.
http://www.datatables.net/release-datatables/extras/Scroller/server-side_processing.html
This happens due to the following:
The logic to fire a redraw is triggered only when the scroll position is outside the redraw trigger boundaries (redrawTop and redrawBottom) AND the user has stopped scrolling. This is the same logic that prevents a DoSing the server:
[code]
if ( this.s.dt.oFeatures.bServerSide ) {
clearTimeout( this.s.drawTO );
this.s.drawTO = setTimeout( function () {
that.s.dt._iDisplayStart = iTopRow;
that.s.dt.oApi._fnCalculateEnd( that.s.dt );
that.s.dt.oApi._fnDraw( that.s.dt );
}, this.s.serverWait );
}
[/code]
However, this logic doesn't take into consideration that a user can scroll outside the trigger boundaries, and back in. The user can still be scrolling, yet the clearTimeout above is never triggered. Thus a premature redraw happens.
The fix for this is the following:
I've added a new scroller default called 'scrollStartedOutsideRedrawBoundary'.
[code]
...
/**
* setTimeout reference for the redraw, used when server-side processing is enabled in the
* DataTables in order to prevent DoSing the server
* @type int
* @default null
*/
"drawTO": null,
/**
* Did the user start scrolling outside the trigger boundary?
*/
"scrollStartedOutsideRedrawBoundary" : false
}, Scroller.oDefaults, oOpts );
...
[/code]
And modified fnScroll to use it.
[code]
"_fnScroll": function ()
..Some other logic...
/* Check if the scroll point is outside the trigger boundary which would required
* a DataTables redraw
*/
if ( iScrollTop < this.s.redrawTop || iScrollTop > this.s.redrawBottom || scrollStartedOutsideRedrawBoundary)
{
..Some logic to calculate iTopRow...
if ( iTopRow != this.s.dt._iDisplayStart || scrollStartedOutsideRedrawBoundary)
{
/* Do the DataTables redraw based on the calculated start point - note that when
* using server-side processing we introduce a small delay to not DoS the server...
*/
if ( this.s.dt.oFeatures.bServerSide ) {
this.s.scrollStartedOutsideRedrawBoundary = true;
clearTimeout( this.s.drawTO );
this.s.drawTO = setTimeout( function () {
that.s.dt._iDisplayStart = iTopRow;
that.s.dt.oApi._fnCalculateEnd( that.s.dt );
that.s.dt.oApi._fnDraw( that.s.dt );
that.s.scrollStartedOutsideRedrawBoundary = false;
}, this.s.serverWait );
}
..Else do stuff and trace...
},
}
[/code]
Thanks,
Ken
http://www.datatables.net/release-datatables/extras/Scroller/server-side_processing.html
This happens due to the following:
The logic to fire a redraw is triggered only when the scroll position is outside the redraw trigger boundaries (redrawTop and redrawBottom) AND the user has stopped scrolling. This is the same logic that prevents a DoSing the server:
[code]
if ( this.s.dt.oFeatures.bServerSide ) {
clearTimeout( this.s.drawTO );
this.s.drawTO = setTimeout( function () {
that.s.dt._iDisplayStart = iTopRow;
that.s.dt.oApi._fnCalculateEnd( that.s.dt );
that.s.dt.oApi._fnDraw( that.s.dt );
}, this.s.serverWait );
}
[/code]
However, this logic doesn't take into consideration that a user can scroll outside the trigger boundaries, and back in. The user can still be scrolling, yet the clearTimeout above is never triggered. Thus a premature redraw happens.
The fix for this is the following:
I've added a new scroller default called 'scrollStartedOutsideRedrawBoundary'.
[code]
...
/**
* setTimeout reference for the redraw, used when server-side processing is enabled in the
* DataTables in order to prevent DoSing the server
* @type int
* @default null
*/
"drawTO": null,
/**
* Did the user start scrolling outside the trigger boundary?
*/
"scrollStartedOutsideRedrawBoundary" : false
}, Scroller.oDefaults, oOpts );
...
[/code]
And modified fnScroll to use it.
[code]
"_fnScroll": function ()
..Some other logic...
/* Check if the scroll point is outside the trigger boundary which would required
* a DataTables redraw
*/
if ( iScrollTop < this.s.redrawTop || iScrollTop > this.s.redrawBottom || scrollStartedOutsideRedrawBoundary)
{
..Some logic to calculate iTopRow...
if ( iTopRow != this.s.dt._iDisplayStart || scrollStartedOutsideRedrawBoundary)
{
/* Do the DataTables redraw based on the calculated start point - note that when
* using server-side processing we introduce a small delay to not DoS the server...
*/
if ( this.s.dt.oFeatures.bServerSide ) {
this.s.scrollStartedOutsideRedrawBoundary = true;
clearTimeout( this.s.drawTO );
this.s.drawTO = setTimeout( function () {
that.s.dt._iDisplayStart = iTopRow;
that.s.dt.oApi._fnCalculateEnd( that.s.dt );
that.s.dt.oApi._fnDraw( that.s.dt );
that.s.scrollStartedOutsideRedrawBoundary = false;
}, this.s.serverWait );
}
..Else do stuff and trace...
},
}
[/code]
Thanks,
Ken
This discussion has been closed.
Replies