React 组件图片库的延迟加载

    xiaoxiao2021-03-26  7

    React 组件图片库的延迟加载

    原文地址:http://andrewhfarmer.com/react-image-gallery/ 水平有限,有误的地方请指正

    事实证明,用react建立一个 带有延迟加载效果的图片库 非常容易, 这里是一个单页面的组件 仅仅只有70行代码 包含 空行 和 注释我将带你 一步一步 的建立这个图片库的组件,当你跟着写完,就会学会啦

    项目准备

    如果你不知道如何启动一个react项目,没关系,下载我的项目,克隆一份到本地 就可以啦。 git clone https://github.com/ahfarmer/minimal-react-starter.git 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) { super(props); this.state = { loading: true, }; }

    2.显示小图标

    - 当图片的状态为加载中时,就显示。 - 创建一个 图片加载的方法 randerSpinner() - 在你的 rnder() 方法中调用它就可以了 //封装 图片正在加载: renderSpinner() { if (!this.state.loading) { // Render nothing if not loading return null; } return ( <span className="spinner" /> ); } // render()中的代码为: 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() { // In React 0.13 use: 'this.refs.gallery.getDOMNode()' 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() { // In React 0.13 use: 'this.refs.gallery.getDOMNode()' 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

    最新回复(0)