Files
ai-course/node_modules/.cache/babel-loader/03264cb7b1f8a7d147d8caff33d402e2a5d22a781392a9f9878913f6688340d9.json

1 line
14 KiB
JSON
Raw Normal View History

{"ast":null,"code":"import{useEffect,useRef,useState}from'react';export const useSectionScroll=function(){let options=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const{duration=1800,// 默认1.8秒\neasing='cubic-bezier(0.4, 0, 0.2, 1)'// Apple风格缓动\n}=options;const[currentSection,setCurrentSection]=useState(0);const[isScrolling,setIsScrolling]=useState(false);const sectionsRef=useRef([]);const touchStartY=useRef(0);// 平滑滚动到指定section\nconst scrollToSection=index=>{if(index<0||index>=sectionsRef.current.length||isScrolling){return;}setIsScrolling(true);const targetSection=sectionsRef.current[index];if(targetSection){// 使用scrollIntoView实现平滑滚动\ntargetSection.scrollIntoView({behavior:'smooth',block:'start'});setCurrentSection(index);// 滚动完成后重置状态\nsetTimeout(()=>{setIsScrolling(false);},duration);}};// 处理滚轮事件\nconst handleWheel=e=>{if(isScrolling){e.preventDefault();return;}const currentSectionElement=sectionsRef.current[currentSection];if(!currentSectionElement)return;// 检查滚动事件是否发生在当前section内\nconst target=e.target;if(!currentSectionElement.contains(target))return;const{scrollTop,scrollHeight,clientHeight}=currentSectionElement;const isAtTop=scrollTop===0;const isAtBottom=Math.abs(scrollHeight-clientHeight-scrollTop)<1;// 向下滚动\nif(e.deltaY>0){// 只有在section底部时才阻止默认行为并切换\nif(isAtBottom&&currentSection<sectionsRef.current.length-1){e.preventDefault();scrollToSection(currentSection+1);}// 否则允许section内部正常滚动\n}// 向上滚动\nelse if(e.deltaY<0){// 只有在section顶部时才阻止默认行为并切换\nif(isAtTop&&currentSection>0){e.preventDefault();scrollToSection(currentSection-1);}// 否则允许section内部正常滚动\n}};// 处理触摸事件(移动端)\nconst handleTouchStart=e=>{touchStartY.current=e.touches[0].clientY;};const handleTouchMove=e=>{if(isScrolling){e.preventDefault();return;}const currentSectionElement=sectionsRef.current[currentSection];if(!currentSectionElement)return;const touchEndY=e.touches[0].clientY;const deltaY=touchStartY.current-touchEndY;const{scrollTop,scrollHeight,clientHeight}=currentSectionElement;const isAtTop=scrollTop===0;const isAtBottom=Math.abs(scrollHeight-clientHeight-scrollTop)<1;// 向上滑动(手指向上移动)\nif(deltaY>50){if(isAtBottom&&currentSection<sectionsRef.current.length-1){e.preventDefault();scrollToSection(currentSection+1);touchStartY.current=touchEndY;}}// 向下滑动(手指向下移动)\nelse if(deltaY<-50){if(isAtTop&&currentSection>0){e.preventDefault();scrollToSection(currentSection-1);touchStartY.current=touchEndY;}}};// 处理键盘事件\nconst handleKeyDown=e=>{if(isScrolling)return;switch(e.key){case'ArrowDown':case'PageDown':if(currentSection<sectionsRef.current.length-1){e.preventDefault();scrollToSection(currentSection+1);}break;case'ArrowUp':case'PageUp':if(currentSection>0){e.preventDefault();scrollToSection(currentSection-1);}break;case'Home':e.preventDefault();scrollToSection(0);break;case'End':e.preventDefault();scrollToSection(sectionsRef.current.length-1);break;}};useEffect(()=>{// 绑定事件监听\nwindow.addEventListener('wheel',handleWheel,{passive:false});window.addEventListener('touchstart',handleTouchStart,{passive:false});window.addEventListener('touchmove',handleTouchMove,{passive:false});window.addEventListener('keydown',handleKeyDown);return()=>{window.removeEventListener('wheel',handleWheel);window.removeEventListener('touchstart',handleTouchStart);window.removeEventListener('touchmove',handleTouchMove);window.removeEventListener('keydown',handleKeyDown);};},[currentSection,isScrolling]);// 注册section元素\nconst registerSection=(element,index)=>{if(element){sectionsRef.current[index]=element;}};return{currentSection,scrollToSection,registerSection,isScrolling};};","map":{"version":3,"names":["useEffect","useRef","useState","useSectionScroll","options","arguments","length","undefined","duration","easing","currentSection","setCurrentSection","is