React 组件图片库的延迟加载
原文地址:http://andrewhfarmer.com/react-image-gallery/ 水平有限,有误的地方请指正
事实证明,用react建立一个 带有延迟加载效果的图片库 非常容易, 这里是一个单页面的组件 仅仅只有70行代码 包含 空行 和 注释我将带你 一步一步 的建立这个图片库的组件,当你跟着写完,就会学会啦
项目准备
如果你不知道如何启动一个react项目,没关系,下载我的项目,克隆一份到本地 就可以啦。
git clone https:
cd
minimal-react-starter
npm install
npm start
这项目文件有个 单一的 HelloWorld 组件,你完全可以动手编辑这个文件(HelloWorld.js) 跟着我写项目的其余的部分,当你保存修改的时候,浏览器会自动刷新。
图库步骤
1.首先,我将写一个新的组件 起个名字 定义一个 属性(propTypes);
import React from
'react';
class Gallery extends React.Component {
}
Gallery.propTypes = {
imageUrls: React.PropTypes.arrayOf(React.PropTypes.string).isRequired,
};
export
default Gallery;
这里 只用到一个属性:一个 imgUrl(图片路径) 的【数组】!!!
正确的使用 React PropTypes(定义属性的类型) 能够节省大量的调试时间,
比如,你的图库组件传递的不是字符串数组,
那么,控制台就清晰的看到 警告提示性的文字。
不要省略 React
.PropTypes.object or React
.PropTypes.any!!!
2.我们写一一些图片地址到 组件中(index.js)
import React
from 'react';
import ReactDOM
from 'react-dom';
import Gallery
from './Gallery';
let urls = [
'/react-image-gallery/img/cat1.jpg',
'/react-image-gallery/img/cat2.jpg',
'/react-image-gallery/img/cat3.jpg',
];
ReactDOM.render(
<Gallery imageUrls={urls}/>,
document.getElementById(
'mount')
);
如果你不喜欢这些 小猫的图片,可以替换成你喜欢的美图, 添加多少张都行
图库的渲染
1.到目前为止,还不能显示出来,我们要编译一下render()中的代码
import React from
'react';
class Gallery extends React.Component {
renderImage(imageUrl) {
return (
<
div>
<img src={imageUrl} />
</
div>
);
}
render() {
return (
<
div className=
"gallery">
<
div className=
"images">
{
this.props.imageUrls.map(imageUrl =>
this.renderImage(imageUrl))}
</
div>
</
div>
);
}
}
Gallery.propTypes = {
imageUrls: React.PropTypes.arrayOf(React.PropTypes.string).isRequired,
};
export
default Gallery;
我的代码都尽量用最新的语法(最简洁和可读的 es6)
ok,我会用2种方式,在render()中用 div 包裹 调用 renderImage 每次加载一个 imgurl(图片地址) 我们将使用 es中的 Array.prototype.map() 来生成数组类型的dom节点
添加延迟图片
如果图片已经加载成功,如果没有 旋转加载的小图标,用户看到空白的图片效果很糟糕,所以接下来我们就添加 小图标, 只需要4步
1.添加状态state
- 首先,组件需要跟踪 图片加载的 状态,显示默认为小图标。
- 在 cunstructor中设置默认状态,默认为true,当组件第一次渲染成功时候就加载图片。
constructor(props) ;
}
2.显示小图标
- 当图片的状态为加载中时,就显示。
- 创建一个 图片加载的方法 randerSpinner()
- 在你的 rnder() 方法中调用它就可以了
renderSpinner() {
if (!
this.state.loading) {
return null;
}
return (
<span className=
"spinner" />
);
}
render() {
return (
<
div className=
"gallery">
{
this.renderSpinner()}
<
div className=
"images">
{
this.props.imageUrls.map(imageUrl =>
this.renderImage(imageUrl))}
</
div>
</
div>
);
}
此时,你会在页面中看到图标一直在加载。。。
3.通过onLoad 和 onError 来加载
接下来我们将添加 onload 和 onError 事件来监控图片加载成功获至失败添加这些属性到你的图片标签上
onload = {this.handleStateChange.bind(this)} onError = {this.handleStateChange.bind(this)}
添加 事件到组件中
handleStateChange() {
const galleryElement =
this.refs.gallery;
this.setState({
loading: !imagesLoaded(galleryElement),
});
}
接下来 我们要 写一个 imageLoader() 方法,括号中接收一个参数,当加载成功,返回一个true. 获取图库 元素的DOM节点 的用ref ,在 render()中写入就可以啦.
<
div className=
"gallery" ref=
"gallery">
获取。用 this.refs.gallery
4.检测所有的图片是否加载完成
imageLoader()方法 不依赖任何组件,所有我们直接在组件外部定义它就好了。
function imagesLoaded(parentNode) {
const imgElements = parentNode.querySelectorAll(
'img');
for (
const img of imgElements) {
if (!img.complete) {
return false;
}
}
return true;
}
完整的代码
import React from
'react';
/**
* Given a DOM element, searches it for <img> tags and checks if all of them
* have finished loading or not.
* @param {Element} parentNode
* @return {Boolean}
*/
function imagesLoaded(parentNode) {
const imgElements = parentNode.querySelectorAll(
'img');
for (const img of imgElements) {
if (!img.complete) {
return false;
}
}
return true;
}
class Gallery extends React.Component {
constructor(props) {
super(props);
this.state = {
loading:
true,
};
}
handleImageChange() {
const galleryElement =
this.refs.gallery;
this.setState({
loading: !imagesLoaded(galleryElement),
});
}
renderSpinner() {
if (!
this.state.loading) {
return null;
}
return (
<span className=
"spinner" />
);
}
renderImage(imageUrl) {
return (
<div>
<img
src={imageUrl}
onLoad={
this.handleImageChange.bind(
this)}
onError={
this.handleImageChange.bind(
this)}
/>
</div>
);
}
render() {
return (
<div className=
"gallery" ref=
"gallery">
{
this.renderSpinner()}
<div className=
"images">
{
this.props.imageUrls.map(imageUrl =>
this.renderImage(imageUrl))}
</div>
</div>
);
}
}
Gallery.propTypes = {
imageUrls: React.PropTypes.arrayOf(React.PropTypes.string).isRequired,
};
export
default Gallery;
转载请注明原文地址: https://ju.6miu.com/read-600008.html