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 problem when scrollbar on html element #1751

Merged
merged 3 commits into from
May 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions spec/e2e/html/1727_resize_scroll_top.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../../../demo/demo.css"/>
<!-- <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gridstack-h5.js"></script> -->
<script src="../../../dist/gridstack-h5.js"></script>
<style>
.topHeader {
Expand All @@ -30,16 +29,37 @@
width: 50px;
box-sizing: border-box;
}
.outer {
display: flex;
}
.main {
flex-grow: 1;
}
.bodyScroll {
height: 2000px;
width: 100px;
flex: 0 0 auto;
border: 3px solid blue;
}
</style>

</head>
<body>
<div class="topHeader">This is the header which brings an offset of 200 px</div>
<div class="row">
<div class="showDistance"></div>
<div class="willScroll">
<div class="grid-stack"></div>
</div>
<div class="outer">
<div class="main">
<div class="topHeader">
This page allows to test scrolling behavior when scroll element is not whole page (html element),
and when the scrolling element is not at the top of the page. Also effects of multiple
scrollbars can be tested, as the html element also can be scrolled.<br>
This is the header which brings an offset of 200 px</div>
<div class="row">
<div class="showDistance"></div>
<div class="willScroll">
<div class="grid-stack"></div>
</div>
</div>
</div>
<div class="bodyScroll">This causes the scrollbar on html element</div>
</div>

<script type="text/javascript">
Expand All @@ -48,7 +68,7 @@
{x: 0, y: 0, w: 2, h: 2, content: "resize-me - check scrolling starts only when in height of gray area, and you can scroll back up as well."},
{x: 3, y: 0, w: 2, h: 2, content: "this is here to have next item positioned way down"},
{x: 3, y: 2, w: 3, h: 2, content: "resize me - scroll will start immediately, but should not be extremely fast"},
{x: 6, y: 0, w: 2, h: 8, content: "this is here to have a scroll bar from the beginning"},
{x: 6, y: 0, w: 2, h: 8, content: "this is here to have a scroll bar on .main div from the beginning"},
];
grid.load(items);
</script>
Expand Down
14 changes: 13 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,19 @@ export class Utils {
static updateScrollResize(event: MouseEvent, el: HTMLElement, distance: number): void {
const scrollEl = this.getScrollElement(el);
const height = scrollEl.clientHeight;
const offsetTop = scrollEl.getBoundingClientRect().top;
// #1745 #1727 - check if mouse position is leaving scroll element.
// event.clientY is relative to origin of viewport, must compare this against position of scrollEl,
// accessible via clientHeight and getBoundingClientRect().top.
// Special situation if scroll element is 'html': here browser spec states that
// clientHeight is height of viewport, but getBoundingClientRect() is rectangle of html element;
// this discrepancy arises because in reality scrollbar is attached to viewport, not html element itself.
let offsetTop : number;
if (scrollEl === this.getScrollElement()) {
offsetTop = 0;
} else {
offsetTop = scrollEl.getBoundingClientRect().top;
}

const pointerPosY = event.clientY - offsetTop;
const top = pointerPosY < distance;
const bottom = pointerPosY > height - distance;
Expand Down