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)
|
||||
|
||||
const LOCK_DURATION_MS = 1000;
|
||||
const SCROLL_EVENTS = [
|
||||
"scroll",
|
||||
"touchmove",
|
||||
"mousedown",
|
||||
"wheel",
|
||||
"DOMMouseScroll",
|
||||
"mousewheel",
|
||||
"keyup"
|
||||
];
|
||||
const LOCK_TIMEOUT_MS = 5000;
|
||||
const SCROLL_EVENTS = ["scroll", "touchmove", "mousedown", "wheel", "keyup"];
|
||||
const SCROLL_TYPES = ["mousedown", "mousewheel", "touchmove", "wheel"];
|
||||
|
||||
function within(threshold, x, y) {
|
||||
|
@ -55,7 +48,7 @@ export default class LockOn {
|
|||
|
||||
clearLock() {
|
||||
this._removeListener();
|
||||
clearInterval(this.interval);
|
||||
window.cancelAnimationFrame(this._requestId);
|
||||
|
||||
if (this.options.finished) {
|
||||
this.options.finished();
|
||||
|
@ -70,7 +63,7 @@ export default class LockOn {
|
|||
window.scrollTo(window.pageXOffset, this.previousTop);
|
||||
}
|
||||
|
||||
this.interval = setInterval(() => this._performLocking(), 50);
|
||||
this._requestId = window.requestAnimationFrame(this._performLocking);
|
||||
|
||||
this._removeListener();
|
||||
this._addListener();
|
||||
|
@ -85,29 +78,32 @@ export default class LockOn {
|
|||
|
||||
_addListener() {
|
||||
const body = document.querySelector("body");
|
||||
const html = document.querySelector("html");
|
||||
|
||||
SCROLL_EVENTS.forEach(event => {
|
||||
body.addEventListener(event, this._scrollListener);
|
||||
html.addEventListener(event, this._scrollListener);
|
||||
});
|
||||
}
|
||||
|
||||
_removeListener() {
|
||||
const body = document.querySelector("body");
|
||||
const html = document.querySelector("html");
|
||||
|
||||
SCROLL_EVENTS.forEach(event => {
|
||||
body.removeEventListener(event, this._scrollListener);
|
||||
html.removeEventListener(event, this._scrollListener);
|
||||
});
|
||||
}
|
||||
|
||||
@bind
|
||||
_performLocking() {
|
||||
const elementTop = this.elementTop();
|
||||
|
||||
// If we can't find the element yet, wait a little bit more
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -129,5 +125,7 @@ export default class LockOn {
|
|||
if (Date.now() - this.startedAt > LOCK_DURATION_MS) {
|
||||
return this.clearLock();
|
||||
}
|
||||
|
||||
this._requestId = window.requestAnimationFrame(this._performLocking);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue