我是react的新手。我试图将我的香草js视差效果转换为反应,但我得到这个错误&;TypeError:无法设置未定义的属性(设置'top')&;
这是我的香草js脚本:<script>
let text = document.getElementById('text');
let sun = document.getElementById('sun');
let house = document.getElementById('house');
let bird1 = document.getElementById('bird1');
let bird2 = document.getElementById('bird2');
let forest = document.getElementById('forest');
let btn = document.getElementById('btn');
let header = document.getElementById('header');
window.addEventListener('scroll', function(){
let value = window.scrollY;
text.style.top = 50 + value * -0.5 + '%';
btn.style.marginTop = value * .7 + 'px';
sun.style.marginTop = value * -2 + 'px';
house.style.marginTop = value * -0.7 + 'px';
bird1.style.top = value * -1.5 + 'px';
bird1.style.left = value * 2 + 'px';
bird2.style.top = value * -1.5 + 'px';
bird2.style.left = value * -5 + 'px';
header.style.top = value * 0.5 + 'px';
})
</script>
我在react中尝试的是:
function ParallaxHero() {
const textRef = useRef();
const sunRef = useRef();
const houseRef = useRef();
const bird1Ref = useRef();
const bird2Ref = useRef();
const forestRef = useRef();
const iconRef = useRef();
const waterRef = useRef();
useEffect(() => {
window.addEventListener("scroll", () => {
let value = window.scrollY;
textRef.style.top = 50 + value * -0.5 + '%';
iconRef.style.marginTop = value * .7 + 'px';
sunRef.style.marginTop = value * -2 + 'px';
houseRef.style.marginTop = value * -0.7 + 'px';
bird1Ref.style.top = value * -1.5 + 'px';
bird1Ref.style.left = value * 2 + 'px';
bird2Ref.style.top = value * -1.5 + 'px';
bird2Ref.style.left = value * -5 + 'px';
waterRef.style.top = value * 0.5 + 'px';
})
})
return (
<>
<div className='parallax relative'>
<h1 ref={textRef} className='parallax-text'>BOOKINGS, IN A HEARTBEAT.</h1>
<Image ref={sunRef} className="parallax-image" src={sunImage} layout="fill" objectFit="cover" alt="Sun Image" />
<Image ref={houseRef} className="parallax-image" src={houseImage} layout="fill" objectFit="cover" alt="Sun Image" />
<Image ref={bird1Ref} className="parallax-image" src={birdOneImage} layout="fill" objectFit="cover" alt="Sun Image" />
<Image ref={bird2Ref} className="parallax-image" src={birdTwoImage} layout="fill" objectFit="cover" alt="Sun Image" />
<Image ref={forestRef} className="parallax-image" src={forestImage} layout="fill" objectFit="cover" alt="Sun Image" />
<a href="#" ref={iconRef} className='parallax-button'>Explore</a>
<Image ref={waterRef} className="parallax-image" src={waterImage} layout="fill" objectFit="cover" alt="Sun Image" />
</div>
</>
)
}
提前谢谢你。
看起来您需要更详细地研究'useRef' https://react.dev/reference/react/useRef#usage
另外,当你要改变像textf .current.style这样的对象时,请保持注意。首先,它不会触发渲染周期,因为它不会改变原始对象。对象总是用'current'来引用,所以任何值的改变都将指向同一个对象。
试试下面的代码:
import { useRef, useEffect } from 'react';
export default function Counter() {
let ref = useRef({style:{}});
useEffect(()=>{
ref.current.style.top = 2;
console.log("Prop: ", ref.current.style.top)
})
}
ref是一个对象,它总是在'current'属性中包含对该元素的当前引用。
还要注意,您添加到窗口的事件侦听器需要在卸载后清理,您可以通过在useEffect中返回清理函数来完成此操作。(否则。style会在undefined上被访问,你会得到一堆"无法读取未定义的属性"错误)
function ParallaxHero() {
const textRef = useRef();
const sunRef = useRef();
const houseRef = useRef();
const bird1Ref = useRef();
const bird2Ref = useRef();
const forestRef = useRef();
const iconRef = useRef();
const waterRef = useRef();
useEffect(() => {
let scrollHandler = () => {
let value = window.scrollY;
textRef.current.style.top = 50 + value * -0.5 + '%';
iconRef.current.style.marginTop = value * .7 + 'px';
sunRef.current.style.marginTop = value * -2 + 'px';
houseRef.current.style.marginTop = value * -0.7 + 'px';
bird1Ref.current.style.top = value * -1.5 + 'px';
bird1Ref.current.style.left = value * 2 + 'px';
bird2Ref.current.style.top = value * -1.5 + 'px';
bird2Ref.current.style.left = value * -5 + 'px';
waterRef.current.style.top = value * 0.5 + 'px';
}
window.addEventListener("scroll", scrollHandler);
return ()=>{
window.removeEventListener("scroll",scrollHandler);
}
})
return (
<>
<div className='parallax relative'>
<h1 ref={textRef} className='parallax-text'>BOOKINGS, IN A HEARTBEAT.</h1>
<Image ref={sunRef} className="parallax-image" src={sunImage} layout="fill" objectFit="cover" alt="Sun Image" />
<Image ref={houseRef} className="parallax-image" src={houseImage} layout="fill" objectFit="cover" alt="Sun Image" />
<Image ref={bird1Ref} className="parallax-image" src={birdOneImage} layout="fill" objectFit="cover" alt="Sun Image" />
<Image ref={bird2Ref} className="parallax-image" src={birdTwoImage} layout="fill" objectFit="cover" alt="Sun Image" />
<Image ref={forestRef} className="parallax-image" src={forestImage} layout="fill" objectFit="cover" alt="Sun Image" />
<a href="#" ref={iconRef} className='parallax-button'>Explore</a>
<Image ref={waterRef} className="parallax-image" src={waterImage} layout="fill" objectFit="cover" alt="Sun Image" />
</div>
</>
)
}