使用 pure javascript 更新滚动上的图像源
Updating image source on scroll using pure javascript
我正在尝试制作一个组件,当它在我的主要组件的 div 标签“infoBG”中被引用时,它会在滚动时更新其源图像。该功能似乎有效,但我猜 return 语句覆盖了该功能,只是 return 原始图像而没有更新。这样做的正确方法是什么,以便函数更新第一个 returned 图像?
function Infoimg () {
window.addEventListener("scroll", event => {
var scrollValue = window.scrollY;
var image = document.getElementById('infoBG');
if (scrollValue>100){
image.setAttribute = ('src','images/ccpLogo.svg');
}else{
image.setAttribute = ('src','images/Passport Stock Photo.svg');
}
console.log(image)
console.log(scrollValue);
});
return(
<img src={'images/Passport Stock Photo.svg'} alt='Info-Background'/>
)
}
在 React 中直接操作 DOM 通常不是一个好主意。相反,依靠挂钩和状态来更新将插入到您的模板中的变量。
在这种情况下,使用 useState
hook 创建新状态以允许读取和写入图像 URL,然后使用 setter 返回的 setter 是有意义的=11=] 更新值。
此外,一些小技巧:
- 您应该使用
useEffect()
并在渲染上添加事件侦听器
- 您还应该 return a function in
useEffect()
确保正确删除滚动事件侦听器以避免潜在的内存泄漏并允许垃圾收集
- 您可以将 if/else 语句简化为简单的 ternary statement
- 您可能希望第一次手动调用
onScroll()
,尤其是当用户可能到达具有缓存滚动位置的页面时(即用户不是从页面顶部开始)
考虑到所有这些要点,这里是您的代码的改进版本:
const [image, setImage] = useState('images/Passport Stock Photo.svg');
useEffect(() => {
const onScroll = () => {
setImage(window.scrollY > 100 ? 'images/ccpLogo.svg' : 'images/Passport Stock Photo.svg');
};
// Note: Listen to scroll event
window.addEventListener('scroll', onScroll);
// Optional: Handle scenario where user arrives at a pre-scrolled position (non-zero scrollY on load)
onScroll();
// Note: Clean up to avoid memory leaks
return () => {
window.removeEventListener('scroll', onScroll);
};
}, []);
return (
<img src={image} alt="Info-Background" />
);
您基本上需要使用 useRef
,这可能会提高性能。请记住 useState
将触发 re-render。但实际上,您只需要更新图像的来源即可。我会用这样的东西。
import { useCallback, useEffect, useRef } from "react";
import "./styles.css";
export default function App() {
const imgRef = useRef();
const middleRef = useRef();
const onScroll = useCallback(() => {
if (imgRef != null) {
var scrollValue = window.scrollY;
if (scrollValue > 100) {
imgRef.current.src = "https://picsum.photos/id/237/200/300";
} else {
imgRef.current.src = "https://picsum.photos/seed/picsum/200/300";
}
console.log(scrollValue);
}
}, []);
useEffect(() => {
window.addEventListener("scroll", onScroll, true);
return () => {
window.removeEventListener("scroll", onScroll, true);
};
}, [onScroll]);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<div ref={middleRef} className="middle" />
<img
ref={imgRef}
src={"https://picsum.photos/seed/picsum/200/300"}
alt="Info-Background"
/>
</div>
);
}
这里是link。您可以检查它在 codesandbox 上的工作情况。
https://codesandbox.io/s/ecstatic-https-hzi5n
我正在尝试制作一个组件,当它在我的主要组件的 div 标签“infoBG”中被引用时,它会在滚动时更新其源图像。该功能似乎有效,但我猜 return 语句覆盖了该功能,只是 return 原始图像而没有更新。这样做的正确方法是什么,以便函数更新第一个 returned 图像?
function Infoimg () {
window.addEventListener("scroll", event => {
var scrollValue = window.scrollY;
var image = document.getElementById('infoBG');
if (scrollValue>100){
image.setAttribute = ('src','images/ccpLogo.svg');
}else{
image.setAttribute = ('src','images/Passport Stock Photo.svg');
}
console.log(image)
console.log(scrollValue);
});
return(
<img src={'images/Passport Stock Photo.svg'} alt='Info-Background'/>
)
}
在 React 中直接操作 DOM 通常不是一个好主意。相反,依靠挂钩和状态来更新将插入到您的模板中的变量。
在这种情况下,使用 useState
hook 创建新状态以允许读取和写入图像 URL,然后使用 setter 返回的 setter 是有意义的=11=] 更新值。
此外,一些小技巧:
- 您应该使用
useEffect()
并在渲染上添加事件侦听器 - 您还应该 return a function in
useEffect()
确保正确删除滚动事件侦听器以避免潜在的内存泄漏并允许垃圾收集 - 您可以将 if/else 语句简化为简单的 ternary statement
- 您可能希望第一次手动调用
onScroll()
,尤其是当用户可能到达具有缓存滚动位置的页面时(即用户不是从页面顶部开始)
考虑到所有这些要点,这里是您的代码的改进版本:
const [image, setImage] = useState('images/Passport Stock Photo.svg');
useEffect(() => {
const onScroll = () => {
setImage(window.scrollY > 100 ? 'images/ccpLogo.svg' : 'images/Passport Stock Photo.svg');
};
// Note: Listen to scroll event
window.addEventListener('scroll', onScroll);
// Optional: Handle scenario where user arrives at a pre-scrolled position (non-zero scrollY on load)
onScroll();
// Note: Clean up to avoid memory leaks
return () => {
window.removeEventListener('scroll', onScroll);
};
}, []);
return (
<img src={image} alt="Info-Background" />
);
您基本上需要使用 useRef
,这可能会提高性能。请记住 useState
将触发 re-render。但实际上,您只需要更新图像的来源即可。我会用这样的东西。
import { useCallback, useEffect, useRef } from "react";
import "./styles.css";
export default function App() {
const imgRef = useRef();
const middleRef = useRef();
const onScroll = useCallback(() => {
if (imgRef != null) {
var scrollValue = window.scrollY;
if (scrollValue > 100) {
imgRef.current.src = "https://picsum.photos/id/237/200/300";
} else {
imgRef.current.src = "https://picsum.photos/seed/picsum/200/300";
}
console.log(scrollValue);
}
}, []);
useEffect(() => {
window.addEventListener("scroll", onScroll, true);
return () => {
window.removeEventListener("scroll", onScroll, true);
};
}, [onScroll]);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<div ref={middleRef} className="middle" />
<img
ref={imgRef}
src={"https://picsum.photos/seed/picsum/200/300"}
alt="Info-Background"
/>
</div>
);
}
这里是link。您可以检查它在 codesandbox 上的工作情况。 https://codesandbox.io/s/ecstatic-https-hzi5n