一開始我想實現一個辦法
就是在滑鼠滾動到指定位置時
我指定的區塊會浮現出來
滑鼠往上滾時,區塊會一起消失
於是此處是一開始的程式
const About=document.getElementsByClassName('about')[0];
const [scroll,setScroll]=useState(
document.body.offsetTop>About.offsetTop?true:false
);
window.onscroll=()=>{
setScroll(
document.body.offsetTop>About.offsetTop?true:false
);
const scrollFade={opacity:scroll?'1':'0',paddingTop:scroll?'100px':'300px'};
想當然爾
開始出現報錯
TypeError: Cannot read properties of undefined (reading 'offsetTop')
(因為我還是個react小白...這邊我還是不知道為什麼會報錯)
甚至是以為前面的document.body.offsetTop有問題
改為window.scrollY
(後來測試是兩種方法都可以用)
於是我把這段的邏輯改成false
const [scroll,setScroll]=useState(false);
讓網頁一開始讀取時
區塊是隱藏的
一開始的想法邏輯是
不管我在網頁何處重新讀取
都會先經過useState的三元判斷式先判斷
來達成區塊是否隱藏的目的
但改為false因為後面的狀態改變
一樣有達到同樣的目的
再來是第二段window.onscroll碰到的問題
在這邊我忘了這個方法重複使用的話
前面使用的方法會被覆蓋過去
於是後來使用addEventLisener
後來完整的寫法為
const [scroll,setScroll]=useState(false);
window.addEventListener('scroll',()=>{
const About=document.getElementsByClassName('about')[0];
setScroll(
window.scrollY>About.getBoundingClientRect().top?true:false
);
});
這邊為什麼會使用getBoundingClientRect()這個方法呢?
是因為發現offsetTop會比getBoundingClientRect().top
感應到的距離來的更遠
offsetTop必須在指定目標過了視窗才會感應
於是選擇使用getBoundingClientRect().top這個方法
更能貼近我所想要的效果
首先,不建議在React裡操作DOM,以及去對DOM做事件綁定等等的操作。
但如果還是有必要取得DOM的資訊的話建議是使用ref
所以如果你要拿 About
這個Component我是建議用ref取binding後,
用ref.current.offsetTop
去取得
我之前的做法是利用 IntersectionObserver 包裝成一個custom hook,
裡面利用ref去綁定我要切換顯示的element。
至於TypeError: Cannot read properties of undefined (reading 'offsetTop')
為什麼會出錯,我的推論是那時候DOM還沒渲染所以讀不到offsetTop
所以useState也無法正常的set initialState
感謝您的建議!!
目前我也還在練習用ref來取得DOM的資訊