@@ -243,73 +243,96 @@ const handleT4ActionCall = async (actionName) => {
243243 }
244244};
245245
246+ let isUpdatingHeight = false ;
247+
246248const 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+
334359const 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// 滚动位置恢复方法
402472const restoreScrollPosition = (scrollPosition ) => {
0 commit comments