mirror of
https://github.com/discourse/discourse.git
synced 2025-01-16 03:52:41 +08:00
FIX: simplify body scroll lock on iOS (#30696)
This will have the following advantages: - removes a very annoying bug which was making text selection super hard on iOS - removes the flashing of header when transitioning from disable to enable body scroll lock
This commit is contained in:
parent
07e5f8907e
commit
b96a9b9896
|
@ -97,37 +97,16 @@ const restoreOverflowSetting = () => {
|
|||
};
|
||||
const setPositionFixed = () =>
|
||||
window.requestAnimationFrame(() => {
|
||||
const $html = document.documentElement;
|
||||
const $body = document.body;
|
||||
if (bodyStyle === void 0) {
|
||||
htmlStyle = { ...$html.style };
|
||||
bodyStyle = { ...$body.style };
|
||||
const { scrollY, scrollX, innerHeight } = window;
|
||||
$html.style.height = "100%";
|
||||
$html.style.overflow = "hidden";
|
||||
$body.style.position = "fixed";
|
||||
$body.style.top = `${-scrollY}px`;
|
||||
$body.style.left = `${-scrollX}px`;
|
||||
$body.style.width = "100%";
|
||||
$body.style.height = "auto";
|
||||
$body.style.touchAction = "none";
|
||||
}
|
||||
});
|
||||
const restorePositionSetting = () => {
|
||||
if (bodyStyle !== void 0) {
|
||||
const y = -parseInt(document.body.style.top, 10);
|
||||
const x = -parseInt(document.body.style.left, 10);
|
||||
const $html = document.documentElement;
|
||||
const $body = document.body;
|
||||
$html.style.height = (htmlStyle == null ? void 0 : htmlStyle.height) || "";
|
||||
$html.style.overflow =
|
||||
(htmlStyle == null ? void 0 : htmlStyle.overflow) || "";
|
||||
$body.style.position = bodyStyle.position || "";
|
||||
$body.style.top = bodyStyle.top || "";
|
||||
$body.style.left = bodyStyle.left || "";
|
||||
$body.style.width = bodyStyle.width || "";
|
||||
$body.style.height = bodyStyle.height || "";
|
||||
$body.style.overflow = bodyStyle.overflow || "";
|
||||
window.scrollTo(x, y);
|
||||
$body.style.touchAction = bodyStyle.touchAction || "";
|
||||
bodyStyle = void 0;
|
||||
}
|
||||
};
|
||||
|
@ -199,43 +178,8 @@ const disableBodyScroll = (targetElement, options) => {
|
|||
} else {
|
||||
setOverflowHidden(options);
|
||||
}
|
||||
if (isIosDevice) {
|
||||
targetElement.ontouchstart = (event) => {
|
||||
if (event.targetTouches.length === 1) {
|
||||
initialClientY = event.targetTouches[0].clientY;
|
||||
}
|
||||
};
|
||||
targetElement.ontouchmove = (event) => {
|
||||
if (event.targetTouches.length === 1) {
|
||||
handleScroll(event, targetElement, options);
|
||||
}
|
||||
};
|
||||
if (!documentListenerAdded) {
|
||||
document.addEventListener(
|
||||
"touchmove",
|
||||
preventDefault,
|
||||
hasPassiveEvents ? { passive: false } : void 0
|
||||
);
|
||||
documentListenerAdded = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
const clearAllBodyScrollLocks = () => {
|
||||
if (isIosDevice) {
|
||||
locks.forEach((lock) => {
|
||||
lock.targetElement.ontouchstart = null;
|
||||
lock.targetElement.ontouchmove = null;
|
||||
});
|
||||
if (documentListenerAdded) {
|
||||
document.removeEventListener(
|
||||
"touchmove",
|
||||
preventDefault,
|
||||
hasPassiveEvents ? { passive: false } : void 0
|
||||
);
|
||||
documentListenerAdded = false;
|
||||
}
|
||||
initialClientY = -1;
|
||||
}
|
||||
if (isIosDevice) {
|
||||
restorePositionSetting();
|
||||
} else {
|
||||
|
@ -261,18 +205,6 @@ const enableBodyScroll = (targetElement) => {
|
|||
locks = locks.filter((lock) => lock.targetElement !== targetElement);
|
||||
locksIndex == null ? void 0 : locksIndex.delete(targetElement);
|
||||
}
|
||||
if (isIosDevice) {
|
||||
targetElement.ontouchstart = null;
|
||||
targetElement.ontouchmove = null;
|
||||
if (documentListenerAdded && locks.length === 0) {
|
||||
document.removeEventListener(
|
||||
"touchmove",
|
||||
preventDefault,
|
||||
hasPassiveEvents ? { passive: false } : void 0
|
||||
);
|
||||
documentListenerAdded = false;
|
||||
}
|
||||
}
|
||||
if (locks.length === 0) {
|
||||
if (isIosDevice) {
|
||||
restorePositionSetting();
|
||||
|
|
|
@ -88,6 +88,7 @@ export default class SwipeModifier extends Modifier {
|
|||
this.element.addEventListener("swipeend", this.onDidEndSwipe);
|
||||
this.element.addEventListener("swipecancel", this.onDidCancelSwipe);
|
||||
this.element.addEventListener("swipe", this.onDidSwipe);
|
||||
this.element.addEventListener("scroll", this.onScroll);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,6 +139,14 @@ export default class SwipeModifier extends Modifier {
|
|||
this.onDidCancelSwipeCallback?.(event.detail);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for scroll event. Prevents scrolling while swiping.
|
||||
*/
|
||||
@bind
|
||||
onScroll(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up the swipe modifier.
|
||||
*/
|
||||
|
@ -150,6 +159,7 @@ export default class SwipeModifier extends Modifier {
|
|||
this.element.removeEventListener("swipeend", this.onDidEndSwipe);
|
||||
this.element.removeEventListener("swipecancel", this.onDidCancelSwipe);
|
||||
this.element.removeEventListener("swipe", this.onDidSwipe);
|
||||
this.element.removeEventListener("scroll", this.onScroll);
|
||||
this._swipeEvents.removeTouchListeners();
|
||||
|
||||
if (this.lockBody) {
|
||||
|
|
|
@ -12,10 +12,6 @@ import { Promise } from "rsvp";
|
|||
import EmojiPickerDetached from "discourse/components/emoji-picker/detached";
|
||||
import InsertHyperlink from "discourse/components/modal/insert-hyperlink";
|
||||
import { SKIP } from "discourse/lib/autocomplete";
|
||||
import {
|
||||
disableBodyScroll,
|
||||
enableBodyScroll,
|
||||
} from "discourse/lib/body-scroll-lock";
|
||||
import { setupHashtagAutocomplete } from "discourse/lib/hashtag-autocomplete";
|
||||
import { emojiUrlFor } from "discourse/lib/text";
|
||||
import userSearch from "discourse/lib/user-search";
|
||||
|
@ -285,22 +281,20 @@ export default class ChatComposer extends Component {
|
|||
}
|
||||
|
||||
@action
|
||||
onTextareaFocusOut(event) {
|
||||
onTextareaFocusOut() {
|
||||
this.isFocused = false;
|
||||
enableBodyScroll(event.target);
|
||||
}
|
||||
|
||||
@action
|
||||
onTextareaFocusIn(event) {
|
||||
this.isFocused = true;
|
||||
const textarea = event.target;
|
||||
disableBodyScroll(textarea);
|
||||
|
||||
if (!this.capabilities.isIOS) {
|
||||
return;
|
||||
}
|
||||
|
||||
// hack to prevent the whole viewport to move on focus input
|
||||
const textarea = event.target;
|
||||
textarea.style.transform = "translateY(-99999px)";
|
||||
textarea.focus();
|
||||
window.requestAnimationFrame(() => {
|
||||
|
|
|
@ -22,5 +22,7 @@
|
|||
color: var(--primary-medium);
|
||||
font-size: var(--font-down-1);
|
||||
padding: 0.5em 0.25em 0.25em;
|
||||
touch-action: none;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user