Eve*_*tss 18 javascript reactjs isomorphic-javascript
在同构呈现的页面图像可以在主script.js
文件之前下载.因此,可以在react
注册onLoad
事件之前加载图像- 从不触发此事件.
script.js
constructor(props) {
super(props);
this.handleImageLoaded = this.handleImageLoaded.bind(this);
}
handleImageLoaded() {
console.log('image loaded');
}
render() {
return (
<img src='image.jpg' onLoad={this.handleImageLoaded} />
);
}
Run Code Online (Sandbox Code Playgroud)
image.jpg
大于script.js
在这种情况下一切正常.在最终加载图像之前注册事件,因此在控制台中是image loaded
消息.
image.jpg
小于script.js
在这种情况下,您可以看到帖子开头描述的问题.onLoad
事件未触发.
为了onLoad
在方案2中触发事件,我该怎么办?
要检测渲染时图像是否准备好,您应该检查complete
纯javascript img
对象上的属性:
constructor(props) {
super(props);
this.state = { loaded: false };
this.handleImageLoaded = this.handleImageLoaded.bind(this);
this.image = React.createRef();
}
componentDidMount() {
const img = this.image.current;
if (img && img.complete) {
this.handleImageLoaded();
}
}
handleImageLoaded() {
if (!this.state.loaded) {
console.log('image loaded');
this.setState({ loaded: true });
}
}
render() {
return (
<img src='image.jpg' ref={this.image} onLoad={this.handleImageLoaded} />
);
}
Run Code Online (Sandbox Code Playgroud)
Sov*_*iut 13
您可以complete
在应用onload
事件之前检查图像上的属性.
if (!img.complete) {
// add onload listener here
}
Run Code Online (Sandbox Code Playgroud)
Ida*_*lan 11
另一种方法是使用 ref 并涵盖这两种情况:
<img
ref={(input) => {
// onLoad replacement for SSR
if (!input) { return; }
const img = input;
const updateFunc = () => {
this.setState({ loaded: true });
};
img.onload = updateFunc;
if (img.complete) {
updateFunc();
}
}}
src={imgSrc}
alt={imgAlt}
/>
Run Code Online (Sandbox Code Playgroud)
使用 Hooks 这一切都变得更整洁了:
const useImageLoaded = () => {
const [loaded, setLoaded] = useState(false)
const ref = useRef()
const onLoad = () => {
setLoaded(true)
}
useEffect(() => {
if (ref.current && ref.current.complete) {
onLoad()
}
})
return [ref, loaded, onLoad]
}
const SomeComponent = ({ src }) => {
const [ref, loaded, onLoad] = useImageLoaded()
return (
<div>
<img ref={ref} onLoad={onLoad} src={src} alt="" />
{loaded && <h1>Loaded!</h1>}
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
小智 6
即使 src 加载失败,img.complete 也是 true。
complete - 返回一个布尔值,如果浏览器已完成获取图像,无论成功与否。如果图像没有 src 值,它也会显示为真。
state = {
isLoading: true,
hasError: false,
}
myRef = React.createRef();
componentDidMount() {
const img = this.myRef.current;
if (img && img.complete) {
if (img.naturalWidth === 0) {
this.handleOnError();
} else {
this.handleImageLoaded();
}
}
}
handleImageLoaded = () => {
if (this.state.isLoading) {
this.setState({ isLoading: false });
}
}
handleOnError = () => {
this.setState({ hasError: true });
}
render() {
return (
<img
src={src}
alt={alt}
ref={this.myRef}
onError={this.handleOnError}
onLoad={this.handleOnLoad}
/>
);
}
Run Code Online (Sandbox Code Playgroud)
componentDidMount() {
const testImg = new Image();
testImg.onerror = this.handleOnError;
testImg.onload = this.handleImageLoaded;
testImg.src = this.props.src; // important to set eventlisteners before src
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
11083 次 |
最近记录: |