Эх сурвалжийг харах

1、优化记住选中卡片样式(工具js通用)

liyanbo 3 сар өмнө
parent
commit
94940340cd

+ 54 - 0
src/utils/pageCss/scrollToCenter.js

@@ -0,0 +1,54 @@
+/**
+ * 滚动容器使指定索引的元素居中显示
+ * @param {HTMLElement} container - 滚动容器元素
+ * @param {number} activeIndex - 当前激活的索引(从0开始)
+ * @param {Object} options - 配置选项
+ * @param {string} options.selector - 子元素选择器,默认为'.middle-inner-box'
+ * @param {boolean} options.validateIndex - 是否验证索引有效性,默认为true
+ * @returns {Promise<boolean>} - 滚动操作是否成功完成
+ */
+export const scrollToCenter = (container, activeIndex, options = {}) => {
+    return new Promise((resolve) => {
+        // 参数验证
+        if (!container || typeof activeIndex !== 'number') {
+            resolve(false);
+            return;
+        }
+
+        const {
+            selector = '.middle-inner-box',
+            validateIndex = true
+        } = options;
+
+        // 验证索引有效性
+        if (validateIndex && activeIndex < 0) {
+            resolve(false);
+            return;
+        }
+
+        // 使用requestAnimationFrame优化滚动
+        requestAnimationFrame(() => {
+            // 找到对应的元素
+            const element = container.querySelector(`${selector}:nth-child(${activeIndex + 1})`);
+            if (element) {
+                // 计算滚动位置,使元素居中
+                const containerWidth = container.clientWidth;
+                const elementLeft = element.offsetLeft;
+                const elementWidth = element.offsetWidth;
+
+                // 计算居中位置
+                const scrollPosition = elementLeft - (containerWidth / 2) + (elementWidth / 2);
+
+                // 平滑滚动到计算的位置
+                container.scrollTo({
+                    left: scrollPosition,
+                    behavior: 'smooth'
+                });
+
+                resolve(true);
+            } else {
+                resolve(false);
+            }
+        });
+    });
+};

+ 3 - 18
src/views/laboratory/ExperimentType.vue

@@ -111,6 +111,7 @@ import {Message} from "@/utils/message/Message.js";
 
 // 获取实验室类型接口
 import { getExperimentTypeId } from '@/api/laboratory/index.js'
+import {scrollToCenter} from "@/utils/pageCss/scrollToCenter.js";
 
 // 常量配置
 const CONSTANTS = {
@@ -162,23 +163,7 @@ watch(activeButton, () => {
 
 // 中间卡片居中显示和放大效果
 const middleBoxWidth = ()=> {
-  if (middleBox.value) {
-    // 找到对应的课程卡片元素
-    const courseElement = middleBox.value.querySelector(`.middle-inner-box:nth-child(${activeButton.value + 1})`);
-    if (courseElement) {
-      // 计算滚动位置,选中的卡片居中
-      const containerWidth = middleBox.value.clientWidth;
-      const elementLeft = courseElement.offsetLeft;
-      const elementWidth = courseElement.offsetWidth;
-      // 计算居中位置
-      const scrollPosition = elementLeft - (containerWidth / 2) + (elementWidth / 2);
-      // 平滑滚动到计算的位置
-      middleBox.value.scrollTo({
-        left: scrollPosition,
-        behavior: 'smooth'
-      });
-    }
-  }
+  scrollToCenter(middleBox.value, activeButton.value);
 }
 
 // 鼠标按下事件处理函数
@@ -244,7 +229,7 @@ const fetchExperimentTypeList = async () => {
         });
 
         // 数据加载完成后,等待下一个DOM更新周期,然后调用middleBoxWidth
-        nextTick(() => {
+        await nextTick(() => {
           middleBoxWidth();
         });
       }

+ 3 - 18
src/views/laboratory/ExperimentalCourses.vue

@@ -106,6 +106,7 @@ import {Message} from "@/utils/message/Message.js";
 import { getCourseByTypeId } from '@/api/laboratory/index.js'
 
 import {DICT_TYPE} from "@/utils/dictUtils.js";
+import {scrollToCenter} from "@/utils/pageCss/scrollToCenter.js";
 
 // 常量配置
 const CONSTANTS = {
@@ -219,23 +220,7 @@ watch(activeButton, () => {
 
 // 中间卡片居中显示和放大效果
 const middleBoxWidth = ()=> {
-  if (middleBox.value) {
-    // 找到对应的课程卡片元素
-    const courseElement = middleBox.value.querySelector(`.middle-inner-box:nth-child(${activeButton.value + 1})`);
-    if (courseElement) {
-      // 计算滚动位置,选中的卡片居中
-      const containerWidth = middleBox.value.clientWidth;
-      const elementLeft = courseElement.offsetLeft;
-      const elementWidth = courseElement.offsetWidth;
-      // 计算居中位置
-      const scrollPosition = elementLeft - (containerWidth / 2) + (elementWidth / 2);
-      // 平滑滚动到计算的位置
-      middleBox.value.scrollTo({
-        left: scrollPosition,
-        behavior: 'smooth'
-      });
-    }
-  }
+  scrollToCenter(middleBox.value, activeButton.value);
 }
 
 // 获取课程数据函数优化
@@ -268,7 +253,7 @@ const fetchCourseData = async () => {
         courseList.value = newCourseItems;
 
         // 数据加载完成后,等待下一个DOM更新周期,然后调用middleBoxWidth
-        nextTick(() => {
+        await nextTick(() => {
           middleBoxWidth();
         });
 

+ 4 - 19
src/views/laboratory/ExperimentalTheme.vue

@@ -100,7 +100,7 @@
 <script setup>
 import {ref, reactive, watch, onMounted, computed, onUnmounted, nextTick} from 'vue'
 // 返回图标
-import { ArrowLeftBold } from '@element-plus/icons-vue';
+import {ArrowLeftBold, Message} from '@element-plus/icons-vue';
 // 导入路由
 import { useRouter } from 'vue-router';
 // 导入按钮图片
@@ -113,6 +113,7 @@ import { logoutLogic } from '@/utils/loginUtils.js'
 // 实验课主题接口
 import { getThemeExperimentList } from '@/api/laboratory/index.js'
 import {aiCourseRoutes} from "@/router/index.js";
+import {scrollToCenter} from "@/utils/pageCss/scrollToCenter.js";
 
 // 常量定义
 const CONSTANTS = {
@@ -166,7 +167,7 @@ const fetchExperimentList = async () => {
       });
 
       // 数据加载完成后,等待下一个DOM更新周期,然后调用middleBoxWidth
-      nextTick(() => {
+      await nextTick(() => {
         middleBoxWidth();
       });
     }
@@ -183,23 +184,7 @@ watch(activeButton, () => {
 
 // 中间卡片居中显示和放大效果
 const middleBoxWidth = ()=> {
-  if (middleBox.value) {
-    // 找到对应的课程卡片元素
-    const courseElement = middleBox.value.querySelector(`.middle-inner-box:nth-child(${activeButton.value + 1})`);
-    if (courseElement) {
-      // 计算滚动位置,选中的卡片居中
-      const containerWidth = middleBox.value.clientWidth;
-      const elementLeft = courseElement.offsetLeft;
-      const elementWidth = courseElement.offsetWidth;
-      // 计算居中位置
-      const scrollPosition = elementLeft - (containerWidth / 2) + (elementWidth / 2);
-      // 平滑滚动到计算的位置
-      middleBox.value.scrollTo({
-        left: scrollPosition,
-        behavior: 'smooth'
-      });
-    }
-  }
+  scrollToCenter(middleBox.value, activeButton.value);
 }
 
 // 鼠标按下事件处理函数

+ 4 - 20
src/views/programming/ProgrammingCourset.vue

@@ -106,6 +106,7 @@ import star02Image from '@/assets/programming/star02.png'
 import star01Image from '@/assets/programming/star01.png'
 import {Message} from "@/utils/message/Message.js";
 import {DICT_TYPE} from "@/utils/dictUtils.js";
+import {scrollToCenter} from "@/utils/pageCss/scrollToCenter.js";
 
 
 // 获取路由实例
@@ -223,26 +224,9 @@ watch(activeButton, () => {
  * 当课程卡片数量超过3个时,调用此函数居中显示选中的课程卡片
  */
 const middleBoxWidth = ()=> {
-  if (contentBox.value && activeButton.value !== -1) {
-    // 使用requestAnimationFrame优化滚动
-    requestAnimationFrame(() => {
-      // 找到对应的课程卡片元素
-      const courseElement = contentBox.value.querySelector(`.slide-item:nth-child(${activeButton.value + 1})`);
-      if (courseElement) {
-        // 计算滚动位置,选中的卡片居中
-        const containerWidth = contentBox.value.clientWidth;
-        const elementLeft = courseElement.offsetLeft;
-        const elementWidth = courseElement.offsetWidth;
-        // 计算居中位置
-        const scrollPosition = elementLeft - (containerWidth / 2) + (elementWidth / 2);
-        // 平滑滚动到计算的位置
-        contentBox.value.scrollTo({
-          left: scrollPosition,
-          behavior: 'smooth'
-        });
-      }
-    });
-  }
+  scrollToCenter(contentBox.value, activeButton.value, {
+    selector: '.slide-item'
+  });
 }
 
 // 获取课程数据函数优化

+ 3 - 18
src/views/programming/ProgrammingGame.vue

@@ -96,6 +96,7 @@ import logoutIcon from '@/assets/icon/logout.png'
 // 退出登录
 import { logoutLogic } from '@/utils/loginUtils.js'
 import {blocklyRoutes} from "@/router/index.js";
+import {scrollToCenter} from "@/utils/pageCss/scrollToCenter.js";
 
 
 // 创建路由实例
@@ -135,7 +136,7 @@ const themeList = async () => {
     });
 
     // 数据加载完成后,等待下一个DOM更新周期,然后调用middleBoxWidth
-    nextTick(() => {
+    await nextTick(() => {
       middleBoxWidth();
     });
   }
@@ -148,23 +149,7 @@ watch(activeButton, () => {
 
 // 中间卡片居中显示和放大效果
 const middleBoxWidth = ()=> {
-  if (middleBox.value) {
-    // 找到对应的课程卡片元素
-    const courseElement = middleBox.value.querySelector(`.middle-inner-box:nth-child(${activeButton.value + 1})`);
-    if (courseElement) {
-      // 计算滚动位置,选中的卡片居中
-      const containerWidth = middleBox.value.clientWidth;
-      const elementLeft = courseElement.offsetLeft;
-      const elementWidth = courseElement.offsetWidth;
-      // 计算居中位置
-      const scrollPosition = elementLeft - (containerWidth / 2) + (elementWidth / 2);
-      // 平滑滚动到计算的位置
-      middleBox.value.scrollTo({
-        left: scrollPosition,
-        behavior: 'smooth'
-      });
-    }
-  }
+  scrollToCenter(middleBox.value, activeButton.value);
 }
 
 // 拖动相关变量

+ 2 - 17
src/views/programming/ProgrammingList.vue

@@ -111,6 +111,7 @@ import trophyImage from '@/assets/programming/trophy.png'
 import star02Image from '@/assets/programming/star02.png'
 import star01Image from '@/assets/programming/star01.png'
 import {Message} from "@/utils/message/Message.js";
+import {scrollToCenter} from "@/utils/pageCss/scrollToCenter.js";
 
 // 获取路由实例
 const router = useRouter()
@@ -179,23 +180,7 @@ watch(activeButton, () => {
 });
 
 const middleBoxWidth = ()=> {
-  if (middleBox.value && activeButton.value !== -1) {
-    // 找到对应的课程卡片元素
-    const courseElement = middleBox.value.querySelector(`.middle-inner-box:nth-child(${activeButton.value + 1})`);
-    if (courseElement) {
-      // 计算滚动位置,选中的卡片居中
-      const containerWidth = middleBox.value.clientWidth;
-      const elementLeft = courseElement.offsetLeft;
-      const elementWidth = courseElement.offsetWidth;
-      // 计算居中位置
-      const scrollPosition = elementLeft - (containerWidth / 2) + (elementWidth / 2);
-      // 平滑滚动到计算的位置
-      middleBox.value.scrollTo({
-        left: scrollPosition,
-        behavior: 'smooth'
-      });
-    }
-  }
+  scrollToCenter(middleBox.value, activeButton.value);
 }
 
 // 拖动相关变量