hookehuyr

perf(StudyCoursePage): 优化滚动和标签页切换的性能

引入防抖函数减少滚动事件触发频率,优化handleScroll函数的逻辑,增加缓冲区域判断。同时,移除handleTabChange函数中的setTimeout,立即更新activeTab的值,提升用户体验。
...@@ -217,8 +217,19 @@ onMounted(async () => { ...@@ -217,8 +217,19 @@ onMounted(async () => {
217 }, 500); 217 }, 500);
218 }); 218 });
219 219
220 +// 防抖函数
221 +const debounce = (fn, delay) => {
222 + let timer = null;
223 + return function (...args) {
224 + if (timer) clearTimeout(timer);
225 + timer = setTimeout(() => {
226 + fn.apply(this, args);
227 + }, delay);
228 + };
229 +};
230 +
220 // 修改handleScroll函数 231 // 修改handleScroll函数
221 -const handleScroll = () => { 232 +const handleScroll = debounce(() => {
222 const detailElement = document.getElementById('detail'); 233 const detailElement = document.getElementById('detail');
223 const catalogElement = document.getElementById('catalog'); 234 const catalogElement = document.getElementById('catalog');
224 const interactionElement = document.getElementById('interaction'); 235 const interactionElement = document.getElementById('interaction');
...@@ -229,17 +240,31 @@ const handleScroll = () => { ...@@ -229,17 +240,31 @@ const handleScroll = () => {
229 isTabFixed.value = currentScrollY >= tabOriginalTop.value; 240 isTabFixed.value = currentScrollY >= tabOriginalTop.value;
230 241
231 const scrollTop = window.scrollY; 242 const scrollTop = window.scrollY;
232 - const catalogOffset = catalogElement.offsetTop - (isTabFixed.value ? tabElement.offsetHeight : 0); 243 + const tabHeight = tabElement.offsetHeight;
233 - const interactionOffset = interactionElement.offsetTop - (isTabFixed.value ? tabElement.offsetHeight : 0); 244 + const buffer = 50; // 缓冲区域
245 +
246 + // 计算每个区域的位置,考虑固定标签页的高度
247 + const detailTop = detailElement.offsetTop - tabHeight - buffer;
248 + const catalogTop = catalogElement.offsetTop - tabHeight - buffer;
249 + const interactionTop = interactionElement.offsetTop - tabHeight - buffer;
234 250
235 - if (scrollTop >= interactionOffset) { 251 + // 获取页面总高度和视口高度
252 + const scrollHeight = document.documentElement.scrollHeight;
253 + const clientHeight = document.documentElement.clientHeight;
254 + const isAtBottom = scrollTop + clientHeight >= scrollHeight - buffer;
255 +
256 + // 判断当前滚动位置所在区域
257 + if (scrollTop <= detailTop) {
258 + activeTab.value = 'detail';
259 + } else if (isAtBottom || scrollTop >= interactionTop) {
236 activeTab.value = 'interaction'; 260 activeTab.value = 'interaction';
237 - } else if (scrollTop >= catalogOffset) { 261 + } else if (scrollTop >= catalogTop && scrollTop < interactionTop) {
238 activeTab.value = 'catalog'; 262 activeTab.value = 'catalog';
239 - } else { 263 + } else if (scrollTop >= detailTop && scrollTop < catalogTop) {
240 activeTab.value = 'detail'; 264 activeTab.value = 'detail';
241 } 265 }
242 -}; 266 +}, 100);
267 +
243 268
244 // 处理标签页切换 269 // 处理标签页切换
245 // 在script setup中添加 270 // 在script setup中添加
...@@ -253,19 +278,18 @@ const getTransitionTiming = (current, previous) => { ...@@ -253,19 +278,18 @@ const getTransitionTiming = (current, previous) => {
253 // 修改handleTabChange函数 278 // 修改handleTabChange函数
254 const handleTabChange = (name) => { 279 const handleTabChange = (name) => {
255 previousTab.value = activeTab.value; 280 previousTab.value = activeTab.value;
281 + activeTab.value = name; // 立即更新activeTab的值
256 let offset = 100; // 调整偏移量, 配合目录的高度 282 let offset = 100; // 调整偏移量, 配合目录的高度
257 - setTimeout(() => { 283 + nextTick(() => {
258 - nextTick(() => { 284 + const element = document.getElementById(name);
259 - const element = document.getElementById(name); 285 + if (element) {
260 - if (element) { 286 + const topOffset = element.offsetTop - offset - parseInt(topWrapperHeight.value);
261 - const topOffset = element.offsetTop - offset - parseInt(topWrapperHeight.value); 287 + window.scrollTo({
262 - window.scrollTo({ 288 + top: topOffset,
263 - top: topOffset, 289 + behavior: 'smooth'
264 - behavior: 'smooth' 290 + });
265 - }); 291 + }
266 - } 292 + });
267 - });
268 - }, 100);
269 }; 293 };
270 294
271 // 课程数据 295 // 课程数据
......