FIX: DEV: Lock-on improvements (#10448)
* DEV: Don't listen for deprecated events https://developer.mozilla.org/en-US/docs/Web/API/Element/DOMMouseScroll_event https://developer.mozilla.org/en-US/docs/Web/API/Element/mousewheel_event * DEV: Listen only on the `body` element * DEV: clearLock after a while if target is missing * DEV: Bind the callback * FIX: Use `requestAnimationFrame` Prevents content jumps
This commit is contained in:
parent
6c09fd4289
commit
e66f95de3a
|
@ -20,15 +20,8 @@ import { bind } from "discourse-common/utils/decorators";
|
||||||
// 2. give up on the scrollbar and implement it ourselves (something that will happen)
|
// 2. give up on the scrollbar and implement it ourselves (something that will happen)
|
||||||
|
|
||||||
const LOCK_DURATION_MS = 1000;
|
const LOCK_DURATION_MS = 1000;
|
||||||
const SCROLL_EVENTS = [
|
const LOCK_TIMEOUT_MS = 5000;
|
||||||
"scroll",
|
const SCROLL_EVENTS = ["scroll", "touchmove", "mousedown", "wheel", "keyup"];
|
||||||
"touchmove",
|
|
||||||
"mousedown",
|
|
||||||
"wheel",
|
|
||||||
"DOMMouseScroll",
|
|
||||||
"mousewheel",
|
|
||||||
"keyup"
|
|
||||||
];
|
|
||||||
const SCROLL_TYPES = ["mousedown", "mousewheel", "touchmove", "wheel"];
|
const SCROLL_TYPES = ["mousedown", "mousewheel", "touchmove", "wheel"];
|
||||||
|
|
||||||
function within(threshold, x, y) {
|
function within(threshold, x, y) {
|
||||||
|
@ -55,7 +48,7 @@ export default class LockOn {
|
||||||
|
|
||||||
clearLock() {
|
clearLock() {
|
||||||
this._removeListener();
|
this._removeListener();
|
||||||
clearInterval(this.interval);
|
window.cancelAnimationFrame(this._requestId);
|
||||||
|
|
||||||
if (this.options.finished) {
|
if (this.options.finished) {
|
||||||
this.options.finished();
|
this.options.finished();
|
||||||
|
@ -70,7 +63,7 @@ export default class LockOn {
|
||||||
window.scrollTo(window.pageXOffset, this.previousTop);
|
window.scrollTo(window.pageXOffset, this.previousTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.interval = setInterval(() => this._performLocking(), 50);
|
this._requestId = window.requestAnimationFrame(this._performLocking);
|
||||||
|
|
||||||
this._removeListener();
|
this._removeListener();
|
||||||
this._addListener();
|
this._addListener();
|
||||||
|
@ -85,29 +78,32 @@ export default class LockOn {
|
||||||
|
|
||||||
_addListener() {
|
_addListener() {
|
||||||
const body = document.querySelector("body");
|
const body = document.querySelector("body");
|
||||||
const html = document.querySelector("html");
|
|
||||||
|
|
||||||
SCROLL_EVENTS.forEach(event => {
|
SCROLL_EVENTS.forEach(event => {
|
||||||
body.addEventListener(event, this._scrollListener);
|
body.addEventListener(event, this._scrollListener);
|
||||||
html.addEventListener(event, this._scrollListener);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_removeListener() {
|
_removeListener() {
|
||||||
const body = document.querySelector("body");
|
const body = document.querySelector("body");
|
||||||
const html = document.querySelector("html");
|
|
||||||
|
|
||||||
SCROLL_EVENTS.forEach(event => {
|
SCROLL_EVENTS.forEach(event => {
|
||||||
body.removeEventListener(event, this._scrollListener);
|
body.removeEventListener(event, this._scrollListener);
|
||||||
html.removeEventListener(event, this._scrollListener);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@bind
|
||||||
_performLocking() {
|
_performLocking() {
|
||||||
const elementTop = this.elementTop();
|
const elementTop = this.elementTop();
|
||||||
|
|
||||||
// If we can't find the element yet, wait a little bit more
|
// If we can't find the element yet, wait a little bit more
|
||||||
if (!this.previousTop && !elementTop) {
|
if (!this.previousTop && !elementTop) {
|
||||||
|
// …but not too long
|
||||||
|
if (Date.now() - this.startedAt > LOCK_TIMEOUT_MS) {
|
||||||
|
this.clearLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
this._requestId = window.requestAnimationFrame(this._performLocking);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,5 +125,7 @@ export default class LockOn {
|
||||||
if (Date.now() - this.startedAt > LOCK_DURATION_MS) {
|
if (Date.now() - this.startedAt > LOCK_DURATION_MS) {
|
||||||
return this.clearLock();
|
return this.clearLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._requestId = window.requestAnimationFrame(this._performLocking);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue