This commit is contained in:
juneix
2026-03-08 21:46:51 +08:00
parent 50d3e765f4
commit 929baf145d
2 changed files with 28 additions and 6 deletions
+14 -2
View File
@@ -850,6 +850,8 @@
renderSlides() { renderSlides() {
this.dom.videoContainer.innerHTML = ''; this.dom.videoContainer.innerHTML = '';
this.dom.videoContainer.className = 'relative w-full h-full transition-transform duration-300 ease-out'; this.dom.videoContainer.className = 'relative w-full h-full transition-transform duration-300 ease-out';
// Clear inline transition left by grid mode, so class-based animation works
this.dom.videoContainer.style.transition = '';
this.dom.videoContainer.style.transform = `translateY(-${this.state.currentIndex * 100}%)`; this.dom.videoContainer.style.transform = `translateY(-${this.state.currentIndex * 100}%)`;
for (let i = 0; i < 3; i++) { for (let i = 0; i < 3; i++) {
@@ -887,9 +889,13 @@
renderGridView() { renderGridView() {
this.dom.slides = null; this.dom.slides = null;
const container = this.dom.videoContainer; const container = this.dom.videoContainer;
container.innerHTML = ''; // Reset page scroll (scrollIntoView can pollute html.scrollTop causing header misalignment)
document.documentElement.scrollTop = 0;
// Disable transition + force reflow before clearing transform, prevents stream offset flickering
container.style.transition = 'none'; container.style.transition = 'none';
void container.offsetHeight;
container.style.transform = 'none'; container.style.transform = 'none';
container.innerHTML = '';
container.className = 'absolute inset-0 z-10 bg-black/40 overflow-hidden flex flex-col'; container.className = 'absolute inset-0 z-10 bg-black/40 overflow-hidden flex flex-col';
const currentVideo = this.state.videos[this.state.currentIndex]; const currentVideo = this.state.videos[this.state.currentIndex];
@@ -1093,9 +1099,15 @@
this.dom.videoDescription.textContent = focusVideo.Overview || 'No Description...'; this.dom.videoDescription.textContent = focusVideo.Overview || 'No Description...';
} }
// Scroll to active card (direct scrollArea op, avoids scrollIntoView polluting html.scrollTop)
requestAnimationFrame(() => { requestAnimationFrame(() => {
const activeEl = gridWrapper.children[this.state.currentIndex]; const activeEl = gridWrapper.children[this.state.currentIndex];
if (activeEl) activeEl.scrollIntoView({ block: 'center', behavior: 'instant' }); if (activeEl && scrollArea) {
const elTop = activeEl.offsetTop;
const elHeight = activeEl.offsetHeight;
const areaHeight = scrollArea.clientHeight;
scrollArea.scrollTop = elTop - (areaHeight / 2) + (elHeight / 2);
}
}); });
lucide.createIcons(); lucide.createIcons();
+14 -4
View File
@@ -909,6 +909,8 @@
renderSlides() { renderSlides() {
this.dom.videoContainer.innerHTML = ''; this.dom.videoContainer.innerHTML = '';
this.dom.videoContainer.className = 'relative w-full h-full transition-transform duration-300 ease-out'; this.dom.videoContainer.className = 'relative w-full h-full transition-transform duration-300 ease-out';
// 清除格子视图残留的内联 transition,防止覆盖 class 里的过渡动画
this.dom.videoContainer.style.transition = '';
this.dom.videoContainer.style.transform = `translateY(-${this.state.currentIndex * 100}%)`; this.dom.videoContainer.style.transform = `translateY(-${this.state.currentIndex * 100}%)`;
// 只初始化 3 个物理槽位 // 只初始化 3 个物理槽位
@@ -951,10 +953,13 @@
renderGridView() { renderGridView() {
this.dom.slides = null; this.dom.slides = null;
const container = this.dom.videoContainer; const container = this.dom.videoContainer;
container.innerHTML = ''; // 重置页面滚动(防止 scrollIntoView 污染 html.scrollTop 导致标题栏错位)
// 先禁用过渡再重置 transform,避免 stream 模式的 translateY 动画在切换时短暂错位 document.documentElement.scrollTop = 0;
// 禁用过渡 + 强制回流,再清零 transform,防止 stream 模式的偏移残留
container.style.transition = 'none'; container.style.transition = 'none';
void container.offsetHeight;
container.style.transform = 'none'; container.style.transform = 'none';
container.innerHTML = '';
// 完全重置为绝对定位的、可滚动的原生网格层 // 完全重置为绝对定位的、可滚动的原生网格层
container.className = 'absolute inset-0 z-10 bg-black/40 overflow-hidden flex flex-col'; container.className = 'absolute inset-0 z-10 bg-black/40 overflow-hidden flex flex-col';
@@ -1176,10 +1181,15 @@
this.dom.videoDescription.textContent = focusVideo.Overview || '没有简介...'; this.dom.videoDescription.textContent = focusVideo.Overview || '没有简介...';
} }
// 滚动到当前高亮的卡片 // 滚动到当前高亮的卡片(直接操作 scrollArea,避免 scrollIntoView 污染 html.scrollTop
requestAnimationFrame(() => { requestAnimationFrame(() => {
const activeEl = gridWrapper.children[this.state.currentIndex]; const activeEl = gridWrapper.children[this.state.currentIndex];
if (activeEl) activeEl.scrollIntoView({ block: 'center', behavior: 'instant' }); if (activeEl && scrollArea) {
const elTop = activeEl.offsetTop;
const elHeight = activeEl.offsetHeight;
const areaHeight = scrollArea.clientHeight;
scrollArea.scrollTop = elTop - (areaHeight / 2) + (elHeight / 2);
}
}); });
lucide.createIcons(); lucide.createIcons();