mirror of
https://github.com/mediacms-io/mediacms.git
synced 2025-11-10 09:28:53 -05:00
fix: Scroll is locked: Need to reload page. (149)
Introduced lockBodyScroll and unlockBodyScroll methods in CustomChaptersOverlay and CustomSettingsMenu to consistently handle body scroll locking and restoration on mobile devices when overlays are opened or closed. This improves iOS compatibility and code maintainability by centralizing scroll management logic.
This commit is contained in:
parent
9a8a34317d
commit
b317f406c3
@ -20,6 +20,7 @@ class CustomChaptersOverlay extends Component {
|
||||
this.touchStartTime = 0;
|
||||
this.touchThreshold = 150; // ms for tap vs scroll detection
|
||||
this.isSmallScreen = window.innerWidth <= 480;
|
||||
this.scrollY = 0; // Track scroll position before locking
|
||||
|
||||
// Bind methods
|
||||
this.createOverlay = this.createOverlay.bind(this);
|
||||
@ -31,6 +32,8 @@ class CustomChaptersOverlay extends Component {
|
||||
this.handleMobileInteraction = this.handleMobileInteraction.bind(this);
|
||||
this.setupResizeListener = this.setupResizeListener.bind(this);
|
||||
this.handleResize = this.handleResize.bind(this);
|
||||
this.lockBodyScroll = this.lockBodyScroll.bind(this);
|
||||
this.unlockBodyScroll = this.unlockBodyScroll.bind(this);
|
||||
|
||||
// Initialize after player is ready
|
||||
this.player().ready(() => {
|
||||
@ -65,6 +68,9 @@ class CustomChaptersOverlay extends Component {
|
||||
|
||||
const el = this.player().el();
|
||||
if (el) el.classList.remove('chapters-open');
|
||||
|
||||
// Restore body scroll on mobile when closing
|
||||
this.unlockBodyScroll();
|
||||
}
|
||||
|
||||
setupResizeListener() {
|
||||
@ -164,6 +170,8 @@ class CustomChaptersOverlay extends Component {
|
||||
this.overlay.style.display = 'none';
|
||||
const el = this.player().el();
|
||||
if (el) el.classList.remove('chapters-open');
|
||||
// Restore body scroll on mobile when closing
|
||||
this.unlockBodyScroll();
|
||||
};
|
||||
chapterClose.appendChild(closeBtn);
|
||||
playlistTitle.appendChild(chapterClose);
|
||||
@ -355,6 +363,37 @@ class CustomChaptersOverlay extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
lockBodyScroll() {
|
||||
if (!this.isMobile) return;
|
||||
|
||||
// Save current scroll position
|
||||
this.scrollY = window.scrollY || window.pageYOffset;
|
||||
|
||||
// Lock body scroll with proper iOS handling
|
||||
document.body.style.overflow = 'hidden';
|
||||
document.body.style.position = 'fixed';
|
||||
document.body.style.top = `-${this.scrollY}px`;
|
||||
document.body.style.left = '0';
|
||||
document.body.style.right = '0';
|
||||
document.body.style.width = '100%';
|
||||
}
|
||||
|
||||
unlockBodyScroll() {
|
||||
if (!this.isMobile) return;
|
||||
|
||||
// Restore body scroll
|
||||
const scrollY = this.scrollY;
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.position = '';
|
||||
document.body.style.top = '';
|
||||
document.body.style.left = '';
|
||||
document.body.style.right = '';
|
||||
document.body.style.width = '';
|
||||
|
||||
// Restore scroll position
|
||||
window.scrollTo(0, scrollY);
|
||||
}
|
||||
|
||||
toggleOverlay() {
|
||||
if (!this.overlay) return;
|
||||
|
||||
@ -369,17 +408,11 @@ class CustomChaptersOverlay extends Component {
|
||||
navigator.vibrate(30);
|
||||
}
|
||||
|
||||
// Prevent body scroll on mobile when overlay is open
|
||||
if (this.isMobile) {
|
||||
if (isHidden) {
|
||||
document.body.style.overflow = 'hidden';
|
||||
document.body.style.position = 'fixed';
|
||||
document.body.style.width = '100%';
|
||||
} else {
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.position = '';
|
||||
document.body.style.width = '';
|
||||
}
|
||||
// Lock/unlock body scroll on mobile when overlay opens/closes
|
||||
if (isHidden) {
|
||||
this.lockBodyScroll();
|
||||
} else {
|
||||
this.unlockBodyScroll();
|
||||
}
|
||||
|
||||
try {
|
||||
@ -390,7 +423,9 @@ class CustomChaptersOverlay extends Component {
|
||||
m.classList.remove('vjs-lock-showing');
|
||||
m.style.display = 'none';
|
||||
});
|
||||
} catch (e) {}
|
||||
} catch {
|
||||
// Ignore errors when closing menus
|
||||
}
|
||||
}
|
||||
|
||||
updateCurrentChapter() {
|
||||
@ -406,7 +441,6 @@ class CustomChaptersOverlay extends Component {
|
||||
currentTime >= chapter.startTime &&
|
||||
(index === this.chaptersData.length - 1 || currentTime < this.chaptersData[index + 1].startTime);
|
||||
|
||||
const handle = item.querySelector('.playlist-drag-handle');
|
||||
const dynamic = item.querySelector('.meta-dynamic');
|
||||
if (isPlaying) {
|
||||
currentChapterIndex = index;
|
||||
@ -463,11 +497,7 @@ class CustomChaptersOverlay extends Component {
|
||||
if (el) el.classList.remove('chapters-open');
|
||||
|
||||
// Restore body scroll on mobile
|
||||
if (this.isMobile) {
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.position = '';
|
||||
document.body.style.width = '';
|
||||
}
|
||||
this.unlockBodyScroll();
|
||||
}
|
||||
}
|
||||
|
||||
@ -479,11 +509,7 @@ class CustomChaptersOverlay extends Component {
|
||||
if (el) el.classList.remove('chapters-open');
|
||||
|
||||
// Restore body scroll on mobile when disposing
|
||||
if (this.isMobile) {
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.position = '';
|
||||
document.body.style.width = '';
|
||||
}
|
||||
this.unlockBodyScroll();
|
||||
|
||||
// Clean up event listeners
|
||||
if (this.handleResize) {
|
||||
|
||||
@ -25,6 +25,7 @@ class CustomSettingsMenu extends Component {
|
||||
this.isMobile = this.detectMobile();
|
||||
this.isSmallScreen = window.innerWidth <= 480;
|
||||
this.touchThreshold = 150; // ms for tap vs scroll detection
|
||||
this.scrollY = 0; // Track scroll position before locking
|
||||
|
||||
// Bind methods
|
||||
this.createSettingsButton = this.createSettingsButton.bind(this);
|
||||
@ -41,6 +42,8 @@ class CustomSettingsMenu extends Component {
|
||||
this.detectMobile = this.detectMobile.bind(this);
|
||||
this.handleMobileInteraction = this.handleMobileInteraction.bind(this);
|
||||
this.setupResizeListener = this.setupResizeListener.bind(this);
|
||||
this.lockBodyScroll = this.lockBodyScroll.bind(this);
|
||||
this.unlockBodyScroll = this.unlockBodyScroll.bind(this);
|
||||
|
||||
// Initialize after player is ready
|
||||
this.player().ready(() => {
|
||||
@ -656,6 +659,8 @@ class CustomSettingsMenu extends Component {
|
||||
if (btnEl) {
|
||||
btnEl.classList.remove('settings-clicked');
|
||||
}
|
||||
// Restore body scroll on mobile when closing
|
||||
this.unlockBodyScroll();
|
||||
};
|
||||
|
||||
closeButton.addEventListener('click', closeFunction);
|
||||
@ -942,6 +947,37 @@ class CustomSettingsMenu extends Component {
|
||||
this.startSubtitleSync();
|
||||
}
|
||||
|
||||
lockBodyScroll() {
|
||||
if (!this.isMobile) return;
|
||||
|
||||
// Save current scroll position
|
||||
this.scrollY = window.scrollY || window.pageYOffset;
|
||||
|
||||
// Lock body scroll with proper iOS handling
|
||||
document.body.style.overflow = 'hidden';
|
||||
document.body.style.position = 'fixed';
|
||||
document.body.style.top = `-${this.scrollY}px`;
|
||||
document.body.style.left = '0';
|
||||
document.body.style.right = '0';
|
||||
document.body.style.width = '100%';
|
||||
}
|
||||
|
||||
unlockBodyScroll() {
|
||||
if (!this.isMobile) return;
|
||||
|
||||
// Restore body scroll
|
||||
const scrollY = this.scrollY;
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.position = '';
|
||||
document.body.style.top = '';
|
||||
document.body.style.left = '';
|
||||
document.body.style.right = '';
|
||||
document.body.style.width = '';
|
||||
|
||||
// Restore scroll position
|
||||
window.scrollTo(0, scrollY);
|
||||
}
|
||||
|
||||
toggleSettings(e) {
|
||||
// e.stopPropagation();
|
||||
const isVisible = this.settingsOverlay.classList.contains('show');
|
||||
@ -954,11 +990,7 @@ class CustomSettingsMenu extends Component {
|
||||
this.stopKeepingControlsVisible();
|
||||
|
||||
// Restore body scroll on mobile when closing
|
||||
if (this.isMobile) {
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.position = '';
|
||||
document.body.style.width = '';
|
||||
}
|
||||
this.unlockBodyScroll();
|
||||
} else {
|
||||
this.settingsOverlay.classList.add('show');
|
||||
this.settingsOverlay.style.display = 'block';
|
||||
@ -972,11 +1004,7 @@ class CustomSettingsMenu extends Component {
|
||||
}
|
||||
|
||||
// Prevent body scroll on mobile when overlay is open
|
||||
if (this.isMobile) {
|
||||
document.body.style.overflow = 'hidden';
|
||||
document.body.style.position = 'fixed';
|
||||
document.body.style.width = '100%';
|
||||
}
|
||||
this.lockBodyScroll();
|
||||
}
|
||||
|
||||
this.speedSubmenu.style.display = 'none'; // Hide submenu when main menu toggles
|
||||
@ -1002,6 +1030,9 @@ class CustomSettingsMenu extends Component {
|
||||
this.settingsOverlay.classList.add('show');
|
||||
this.settingsOverlay.style.display = 'block';
|
||||
|
||||
// Lock body scroll when opening
|
||||
this.lockBodyScroll();
|
||||
|
||||
// Hide other submenus and show subtitles submenu
|
||||
this.speedSubmenu.style.display = 'none';
|
||||
if (this.qualitySubmenu) this.qualitySubmenu.style.display = 'none';
|
||||
@ -1072,11 +1103,7 @@ class CustomSettingsMenu extends Component {
|
||||
}
|
||||
|
||||
// Restore body scroll on mobile when closing
|
||||
if (this.isMobile) {
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.position = '';
|
||||
document.body.style.width = '';
|
||||
}
|
||||
this.unlockBodyScroll();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1417,6 +1444,8 @@ class CustomSettingsMenu extends Component {
|
||||
if (btnEl) {
|
||||
btnEl.classList.remove('settings-clicked');
|
||||
}
|
||||
// Restore body scroll on mobile when closing
|
||||
this.unlockBodyScroll();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1493,11 +1522,7 @@ class CustomSettingsMenu extends Component {
|
||||
}
|
||||
|
||||
// Restore body scroll on mobile when disposing
|
||||
if (this.isMobile) {
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.position = '';
|
||||
document.body.style.width = '';
|
||||
}
|
||||
this.unlockBodyScroll();
|
||||
|
||||
// Remove DOM elements
|
||||
if (this.settingsOverlay) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user