Преглед изворни кода

Merge branch 'master' of http://121.40.40.223:3000/zizhong.wang/dtScreen

hebotao пре 2 недеља
родитељ
комит
dc5593a37f
2 измењених фајлова са 37 додато и 10 уклоњено
  1. 32 9
      src/components/ui/SeamlessScroll.vue
  2. 5 1
      src/views/Home.vue

+ 32 - 9
src/components/ui/SeamlessScroll.vue

@@ -16,6 +16,7 @@ export default {
   data() {
     return {
       scrollTimer: null,
+      _initTimer: null,
       currentTop: 0,
       resetHeight: 0,
       isScrollable: false
@@ -44,6 +45,11 @@ export default {
   mounted() {
     console.log('✅ SeamlessScroll: 组件已挂载,准备初始化滚动');
     this.initScroll();
+    // 全屏切换后容器高度变化,需要重新初始化滚动
+    this._onFullscreenChange = () => {
+      setTimeout(() => this.initScroll(), 300);
+    };
+    document.addEventListener('fullscreenchange', this._onFullscreenChange);
   },
   watch: {
     data: {
@@ -56,10 +62,22 @@ export default {
   },
   beforeDestroy() {
     this.pause();
+    if (this._initTimer) {
+      clearTimeout(this._initTimer);
+      this._initTimer = null;
+    }
+    if (this._onFullscreenChange) {
+      document.removeEventListener('fullscreenchange', this._onFullscreenChange);
+    }
   },
   methods: {
     initScroll() {
       this.pause();
+      // 清除上一次未执行完的延时器,防止多个 setTimeout 同时触发 resume
+      if (this._initTimer) {
+        clearTimeout(this._initTimer);
+        this._initTimer = null;
+      }
       this.currentTop = 0;
       if (this.$refs.scrollRef) this.$refs.scrollRef.scrollTop = 0;
 
@@ -71,14 +89,12 @@ export default {
 
       this.$nextTick(() => {
         // 加大一点延时,给表格充足的撑开时间
-        setTimeout(() => {
+        this._initTimer = setTimeout(() => {
+          this._initTimer = null;
           const wrapper = this.$refs.scrollRef;
           if (!wrapper) return;
-          
-          const measureEl = wrapper.querySelector(this.measureSelector);
 
-          // 【排查神器】:打印高度对比
-        //   console.log(`📏 尺寸核对 -> 容器可视高度: ${wrapper.clientHeight}px, 内容真实总高: ${wrapper.scrollHeight}px`);
+          const measureEl = wrapper.querySelector(this.measureSelector);
 
           // 如果容器高度等于或大于内容高度,说明没有溢出,肯定滚不动
           if (wrapper.scrollHeight <= wrapper.clientHeight) {
@@ -87,22 +103,29 @@ export default {
           }
 
           this.resetHeight = measureEl ? measureEl.offsetHeight / 2 : wrapper.scrollHeight / 2;
-        //   console.log('🚀 SeamlessScroll: 滚动初始化成功!复位锚点高度为:', this.resetHeight);
 
           this.resume();
-        }, 100); 
+        }, 100);
       });
     },
     resume() {
       if ((!this.data || this.data.length <= this.limit) || this.resetHeight <= 0) return;
+      // 防止重复调用产生多个动画循环
+      this.pause();
       const step = () => {
         const wrapper = this.$refs.scrollRef;
-        if (!wrapper) return;
+        if (!wrapper) {
+          // ref 暂时丢失(Vue 重渲染),不断链,等下一帧重试
+          this.scrollTimer = requestAnimationFrame(step);
+          return;
+        }
 
         this.currentTop += this.speed;
         wrapper.scrollTop = Math.floor(this.currentTop);
 
-        if (wrapper.scrollTop >= this.resetHeight) {
+        // 到达复位点,或者已滚到底部无法继续时,都重置
+        const maxScroll = wrapper.scrollHeight - wrapper.clientHeight;
+        if (wrapper.scrollTop >= this.resetHeight || (maxScroll > 0 && wrapper.scrollTop >= maxScroll)) {
           this.currentTop = 0;
           wrapper.scrollTop = 0;
         }

+ 5 - 1
src/views/Home.vue

@@ -292,10 +292,14 @@ export default {
   display: flex;
   flex-direction: column;
   gap: 16px;
+  height: 100%;
 }
 
 .panel-item {
-  height: 254px;
+  /* 可用高度 = 100vh - 80px(header) - 20px(上padding) - 60px(下padding)
+     3个面板 + 2个gap(16px) = 32px
+     每个面板 = (100vh - 192px) / 3 */
+  height: calc((100vh - 192px) / 3);
 }
 
 .table-panel ::v-deep .panel-content {