Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix scroll doesn't reset to top #115

Merged

Conversation

quixotically
Copy link
Contributor

Description

This fixes the bug where if you were to scroll to the bottom (or anywhere below the top), then resize the screen bigger until there is no scrollbar, the content used to not scroll up as the 'clientHeight' was increasing.

Motivation and Context

Fixes #87

How Has This Been Tested?

Tested manually by sizing the screen smaller to create a scrollbar, scrolling to bottom, then increasing the size until there is no scrollbar. Did this several times and used logging to ensure that bad state was not happening.

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.

var maxScrollTop = scrollContentHeight - bodyHeight;
// Handle the case where the scrollTop is beyond the maxScrollTop, such as when the user is completely scrolled
// down and resizes the viewport to be smaller vertically
if (scrollTop > maxScrollTop || scrollTop === 0) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately I couldn't come up with a way to do the scrollTop === 0 once. If the 0 logic is removed, scrolling slowly back up can cause the scrollTop to never update all the way back to 0. There may be a better way, but for now this seems to work well enough.

@KamranAsif
Copy link
Contributor

There seems to be a bug with your zero condition. If I open the dev server and open the JSON Data example, I end up starting from the bottom without doing anything

image

@KamranAsif
Copy link
Contributor

Another big bug is when I resize the page, I end up jumping to the bottom of a large table. I expect to not change my first index

// This calculation is synonymous to Element.scrollTop
var scrollTop = firstRowIndex && Math.abs(firstRowOffset - this._scrollHelper.getRowPosition(firstRowIndex));
if (scrollTop >= 0) {
var maxScrollTop = maxScrollY ? scrollContentHeight - bodyHeight : 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maxScrollY is already this value. We don't need to recalculate maxScrollTop

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah true, removed maxScrollTop

@@ -1056,6 +1056,21 @@ var FixedDataTable = React.createClass({

this._scrollHelper.setViewportHeight(bodyHeight);

// This calculation is synonymous to Element.scrollTop
var scrollTop = firstRowIndex && Math.abs(firstRowOffset - this._scrollHelper.getRowPosition(firstRowIndex));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use && as an if statement

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to
var scrollTop = firstRowIndex ? Math.abs(firstRowOffset - this._scrollHelper.getRowPosition(firstRowIndex)) : 0;

Was also able to get rid of the following if statement (line 1061) because of this

var maxScrollTop = maxScrollY ? scrollContentHeight - bodyHeight : 0;
// Handle the case where the scrollTop is beyond the maxScrollTop, such as when the user is completely scrolled
// down and resizes the viewport to be smaller vertically
if (scrollTop > maxScrollTop || maxScrollTop === 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What case does maxScrollTop === zero catch?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it! Originally I couldn't come up with a way to do the maxScrollTop === 0 once. Before, if the 0 logic was removed, scrolling slowly back up can cause the scrollTop to never update all the way back to 0. At the time I couldn't figure out how to do the check so that we only set back to 0 once.

But I found out how to do it. I have the previous scrollY, so:
if (scrollTop > maxScrollY || (oldState && oldState.scrollY !== 0 && maxScrollY === 0)) {

See in my newest commit.

@@ -1056,6 +1056,19 @@ var FixedDataTable = React.createClass({

this._scrollHelper.setViewportHeight(bodyHeight);

// This calculation is synonymous to Element.scrollTop
var scrollTop = firstRowIndex ? Math.abs(firstRowOffset - this._scrollHelper.getRowPosition(firstRowIndex)) : 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

firstRowIndex should always exist. you can get rid of the if statement here.
Also, is the absolute value necessary? When would we get a negative value here

@@ -1056,6 +1056,19 @@ var FixedDataTable = React.createClass({

this._scrollHelper.setViewportHeight(bodyHeight);

// This calculation is synonymous to Element.scrollTop
var scrollTop = firstRowIndex != null ? Math.abs(firstRowOffset - this._scrollHelper.getRowPosition(firstRowIndex)) : 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

firstRowIndex is always defined, you don't need the null check

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, thanks. Removed

// Handle the case where the scrollTop is beyond the maxScrollY, such as when the user is completely scrolled
// down and resizes the viewport to be smaller vertically. The other case is when resizing the viewport large enough
// so that a scrollbar is not necessary anymore, to make sure we set the scrollTop back to 0.
if (scrollTop > maxScrollY || (oldState && oldState.scrollY !== 0 && maxScrollY === 0)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use scrollY instead of oldState.scrollY. We might have modified it by the time we reach this line

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary anymore because of your above comment

@@ -1056,6 +1056,19 @@ var FixedDataTable = React.createClass({

this._scrollHelper.setViewportHeight(bodyHeight);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After some investigation, it seems the real bug is this line. We update the viewport height after having calculated the rows. This makes our clamping operation invalid.

I think all we really need to do is check if scrollTop === scrollY.

var scrollTop = firstRowIndex != null ? Math.abs(firstRowOffset - this._scrollHelper.getRowPosition(firstRowIndex)) : 0;
// Handle the case where the scrollTop is beyond the maxScrollY, such as when the user is completely scrolled
// down and resizes the viewport to be smaller vertically. The other case is when resizing the viewport large enough
// so that a scrollbar is not necessary anymore, to make sure we set the scrollTop back to 0.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is really only one case here. Your second comment about resizing the viewport large enough that the scrollbar isn't necessary necessitates that we hit the first case, of having scrollTop being beyond maxScrollY

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, true

@KamranAsif KamranAsif merged commit b2c4e2c into schrodinger:master Feb 6, 2017
@quixotically quixotically deleted the SS-18521-ScrollDoesntResetToTop branch February 6, 2017 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

The scroll bar disappears and the user can't see all the data from the table.
2 participants