Skip to content

Commit 64040f0

Browse files
author
Taois
committed
feat:多级目录返回根目录
1 parent 82e9c8f commit 64040f0

File tree

1 file changed

+153
-83
lines changed

1 file changed

+153
-83
lines changed

dashboard/src/components/VideoGrid.vue

Lines changed: 153 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -243,73 +243,96 @@ const handleT4ActionCall = async (actionName) => {
243243
}
244244
};
245245
246+
let isUpdatingHeight = false;
247+
246248
const updateScrollAreaHeight = () => {
249+
// 防止递归调用
250+
if (isUpdatingHeight) {
251+
return;
252+
}
253+
254+
isUpdatingHeight = true;
255+
247256
nextTick(() => {
248257
setTimeout(() => {
249-
const container = containerRef.value;
250-
if (!container) return;
251-
252-
// 查找父级内容区域
253-
const contentArea = container.closest('.content-area') || container.parentElement;
254-
const footer = container.querySelector('.stats-footer');
255-
const footerHeight = (props.showStats && footer) ? footer.offsetHeight : 0;
256-
257-
// 查找CategoryNavigation组件来获取其实际高度
258-
const categoryNav = document.querySelector('.category-nav-container');
259-
const categoryNavHeight = categoryNav ? categoryNav.offsetHeight : 0;
260-
261-
let containerHeight = contentArea ? contentArea.offsetHeight : 0;
262-
if (containerHeight <= 0) {
263-
// 备用方案:使用窗口高度减去导航栏等固定元素高度
264-
// 考虑到CategoryNavigation的高度变化
265-
const baseHeight = Math.max(window.innerHeight - 120, 500);
266-
containerHeight = baseHeight;
267-
}
258+
try {
259+
const container = containerRef.value;
260+
if (!container) {
261+
isUpdatingHeight = false;
262+
return;
263+
}
268264
269-
console.log(`CategoryNavigation高度: ${categoryNavHeight}px, 内容区域高度: ${containerHeight}px`);
265+
// 查找父级内容区域
266+
const contentArea = container.closest('.content-area') || container.parentElement;
267+
const footer = container.querySelector('.stats-footer');
268+
const footerHeight = (props.showStats && footer) ? footer.offsetHeight : 0;
269+
270+
// 查找CategoryNavigation组件来获取其实际高度
271+
const categoryNav = document.querySelector('.category-nav-container');
272+
const categoryNavHeight = categoryNav ? categoryNav.offsetHeight : 0;
273+
274+
let containerHeight = contentArea ? contentArea.offsetHeight : 0;
275+
if (containerHeight <= 0) {
276+
// 备用方案:使用窗口高度减去导航栏等固定元素高度
277+
// 考虑到CategoryNavigation的高度变化
278+
const baseHeight = Math.max(window.innerHeight - 120, 500);
279+
containerHeight = baseHeight;
280+
}
270281
271-
// 改进的高度计算逻辑:
272-
// 1. 正确计算网格列数(基于容器宽度)
273-
// 2. 估算内容实际需要的高度
274-
// 3. 智能调整容器高度以确保滚动翻页正常工作
275-
276-
const videoCount = props.videos ? props.videos.length : 0;
277-
278-
// 获取容器宽度来计算列数
279-
const containerWidth = container.offsetWidth || Math.max(window.innerWidth - 240, 800); // 减去侧边栏宽度
280-
const itemWidth = 200; // 每个视频项的估算宽度
281-
const gridCols = Math.min(Math.floor(containerWidth / itemWidth), 8); // 基于宽度计算列数,最多8列
282-
283-
const estimatedItemHeight = 328; // 根据F12实际测量的高度(图片+文字)
284-
const estimatedRows = videoCount > 0 ? Math.ceil(videoCount / Math.max(gridCols, 1)) : 0;
285-
const estimatedContentHeight = estimatedRows * estimatedItemHeight + 16; // 减少padding估算
286-
287-
// 智能高度调整策略 - 考虑CategoryNavigation的动态高度
288-
let heightReduction = 4; // 默认只减去少量padding
289-
290-
// 如果没有视频数据,使用保守的高度减值来为后续数据加载预留空间
291-
if (videoCount === 0) {
292-
// 对于空数据,需要确保有足够的滚动空间来触发翻页
293-
// 减去更多高度以确保滚动条出现
294-
heightReduction = Math.min(containerHeight * 0.4, 300); // 增加减值比例
295-
console.log(`无视频数据,使用保守高度减值: ${heightReduction}px`);
296-
} else if (estimatedContentHeight < containerHeight) {
297-
// 有数据但内容不足时,需要减少容器高度以触发滚动
298-
// 策略:容器高度 = 内容高度 - 150px(确保有足够滚动空间)
299-
const minDisplayHeight = Math.floor(estimatedItemHeight * 1.2) + 60; // 至少显示1.2行
300-
const idealHeight = estimatedContentHeight - 5; // 增加滚动空间
301-
const targetHeight = Math.max(idealHeight, minDisplayHeight, containerHeight * 0.3); // 降低最小比例
302-
heightReduction = Math.max(containerHeight - targetHeight, 50); // 增加最小减值
303-
console.log(`内容高度不足,估算内容高度: ${estimatedContentHeight}px, 理想高度: ${idealHeight}px, 最小显示高度: ${minDisplayHeight}px, 容器高度: ${containerHeight}px, 调整高度减值: ${heightReduction}px`);
304-
} else {
305-
// 内容充足时,减少一些高度确保滚动正常
306-
heightReduction = Math.min(containerHeight * 0.02, 20);
307-
console.log(`内容充足,使用标准高度减值: ${heightReduction}px`);
282+
console.log(`CategoryNavigation高度: ${categoryNavHeight}px, 内容区域高度: ${containerHeight}px`);
283+
284+
// 改进的高度计算逻辑:
285+
// 1. 正确计算网格列数(基于容器宽度)
286+
// 2. 估算内容实际需要的高度
287+
// 3. 智能调整容器高度以确保滚动翻页正常工作
288+
289+
const videoCount = props.videos ? props.videos.length : 0;
290+
291+
// 获取容器宽度来计算列数
292+
const containerWidth = container.offsetWidth || Math.max(window.innerWidth - 240, 800); // 减去侧边栏宽度
293+
const itemWidth = 200; // 每个视频项的估算宽度
294+
const gridCols = Math.min(Math.floor(containerWidth / itemWidth), 8); // 基于宽度计算列数,最多8列
295+
296+
const estimatedItemHeight = 328; // 根据F12实际测量的高度(图片+文字)
297+
const estimatedRows = videoCount > 0 ? Math.ceil(videoCount / Math.max(gridCols, 1)) : 0;
298+
const estimatedContentHeight = estimatedRows * estimatedItemHeight + 16; // 减少padding估算
299+
300+
// 智能高度调整策略 - 考虑CategoryNavigation的动态高度
301+
let heightReduction = 4; // 默认只减去少量padding
302+
303+
// 如果没有视频数据,使用保守的高度减值来为后续数据加载预留空间
304+
if (videoCount === 0) {
305+
// 对于空数据,需要确保有足够的滚动空间来触发翻页
306+
// 减去更多高度以确保滚动条出现
307+
heightReduction = Math.min(containerHeight * 0.4, 300); // 增加减值比例
308+
console.log(`无视频数据,使用保守高度减值: ${heightReduction}px`);
309+
} else if (estimatedContentHeight < containerHeight) {
310+
// 有数据但内容不足时,需要减少容器高度以触发滚动
311+
// 策略:容器高度 = 内容高度 - 150px(确保有足够滚动空间)
312+
const minDisplayHeight = Math.floor(estimatedItemHeight * 1.2) + 60; // 至少显示1.2行
313+
const idealHeight = estimatedContentHeight - 5; // 增加滚动空间
314+
const targetHeight = Math.max(idealHeight, minDisplayHeight, containerHeight * 0.3); // 降低最小比例
315+
heightReduction = Math.max(containerHeight - targetHeight, 50); // 增加最小减值
316+
console.log(`内容高度不足,估算内容高度: ${estimatedContentHeight}px, 理想高度: ${idealHeight}px, 最小显示高度: ${minDisplayHeight}px, 容器高度: ${containerHeight}px, 调整高度减值: ${heightReduction}px`);
317+
} else {
318+
// 内容充足时,减少一些高度确保滚动正常
319+
heightReduction = Math.min(containerHeight * 0.02, 20);
320+
console.log(`内容充足,使用标准高度减值: ${heightReduction}px`);
321+
}
322+
323+
const newHeight = Math.max(containerHeight - footerHeight - heightReduction, 250); // 降低最小高度
324+
325+
// 只有当高度真正发生变化时才更新
326+
if (Math.abs(scrollAreaHeight.value - newHeight) > 5) {
327+
scrollAreaHeight.value = newHeight;
328+
}
329+
330+
console.log(`视频数量: ${videoCount}, 估算行数: ${estimatedRows}, 列数: ${gridCols}, 容器宽度: ${containerWidth}px, 最终高度: ${newHeight}px`);
331+
} catch (error) {
332+
console.warn('updateScrollAreaHeight error:', error);
333+
} finally {
334+
isUpdatingHeight = false;
308335
}
309-
310-
const newHeight = Math.max(containerHeight - footerHeight - heightReduction, 250); // 降低最小高度
311-
console.log(`视频数量: ${videoCount}, 估算行数: ${estimatedRows}, 列数: ${gridCols}, 容器宽度: ${containerWidth}px, 最终高度: ${newHeight}px`);
312-
scrollAreaHeight.value = newHeight;
313336
}, 100); // 增加延迟确保DOM完全渲染
314337
});
315338
};
@@ -331,22 +354,37 @@ const handleScroll = (e) => {
331354
};
332355
333356
// 检测文本是否超出容器宽度
357+
let isCheckingOverflow = false;
358+
334359
const checkTextOverflow = () => {
360+
// 防止递归调用
361+
if (isCheckingOverflow) {
362+
return;
363+
}
364+
365+
isCheckingOverflow = true;
366+
335367
nextTick(() => {
336368
setTimeout(() => {
337-
const titleElements = document.querySelectorAll('.video_list_item_title .title-text');
338-
titleElements.forEach(element => {
339-
const container = element.parentElement;
340-
const containerWidth = container.offsetWidth - 16; // 减去padding
341-
const textWidth = element.scrollWidth;
342-
343-
// 如果文本宽度超过容器宽度,添加overflow属性启用跑马灯
344-
if (textWidth > containerWidth) {
345-
element.setAttribute('data-overflow', 'true');
346-
} else {
347-
element.removeAttribute('data-overflow');
348-
}
349-
});
369+
try {
370+
const titleElements = document.querySelectorAll('.video_list_item_title .title-text');
371+
titleElements.forEach(element => {
372+
const container = element.parentElement;
373+
const containerWidth = container.offsetWidth - 16; // 减去padding
374+
const textWidth = element.scrollWidth;
375+
376+
// 如果文本宽度超过容器宽度,添加overflow属性启用跑马灯
377+
if (textWidth > containerWidth) {
378+
element.setAttribute('data-overflow', 'true');
379+
} else {
380+
element.removeAttribute('data-overflow');
381+
}
382+
});
383+
} catch (error) {
384+
console.warn('checkTextOverflow error:', error);
385+
} finally {
386+
isCheckingOverflow = false;
387+
}
350388
}, 100); // 延迟确保DOM渲染完成
351389
});
352390
};
@@ -360,11 +398,20 @@ onMounted(() => {
360398
const observeFilterChanges = () => {
361399
const categoryNav = document.querySelector('.category-nav-container');
362400
if (categoryNav && containerRef.value) {
401+
let observerTimer = null;
402+
363403
const observer = new MutationObserver(() => {
364-
// 延迟执行以确保DOM更新完成
365-
setTimeout(() => {
366-
updateScrollAreaHeight();
367-
}, 100);
404+
// 防抖处理,避免频繁触发
405+
if (observerTimer) {
406+
clearTimeout(observerTimer);
407+
}
408+
409+
observerTimer = setTimeout(() => {
410+
// 只有当组件还存在时才执行更新
411+
if (containerRef.value && !isUpdatingHeight) {
412+
updateScrollAreaHeight();
413+
}
414+
}, 200);
368415
});
369416
370417
observer.observe(categoryNav, {
@@ -392,11 +439,34 @@ onBeforeUnmount(() => {
392439
}
393440
});
394441
395-
// 当视频数据或显示统计信息变化时,更新高度和检测文本溢出
396-
watch(() => [props.videos, props.showStats], () => {
397-
updateScrollAreaHeight();
398-
checkTextOverflow();
399-
});
442+
// 监听videos变化,重新计算高度和检查文本溢出
443+
// 使用防抖和条件检查避免递归更新
444+
let updateTimer = null;
445+
let lastVideosLength = 0;
446+
let lastShowStats = false;
447+
448+
watch([() => props.videos, () => props.showStats], ([newVideos, newShowStats]) => {
449+
// 避免不必要的更新
450+
if (newVideos.length === lastVideosLength && newShowStats === lastShowStats) {
451+
return;
452+
}
453+
454+
lastVideosLength = newVideos.length;
455+
lastShowStats = newShowStats;
456+
457+
// 清除之前的定时器
458+
if (updateTimer) {
459+
clearTimeout(updateTimer);
460+
}
461+
462+
// 使用防抖避免频繁更新
463+
updateTimer = setTimeout(() => {
464+
nextTick(() => {
465+
checkTextOverflow();
466+
updateScrollAreaHeight();
467+
});
468+
}, 100);
469+
}, { deep: true });
400470
401471
// 滚动位置恢复方法
402472
const restoreScrollPosition = (scrollPosition) => {

0 commit comments

Comments
 (0)