iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >如何使用react-virtualized实现图片动态高度长列表
  • 305
分享到

如何使用react-virtualized实现图片动态高度长列表

2023-06-15 06:06:24 305人浏览 独家记忆
摘要

小编给大家分享一下如何使用React-virtualized实现图片动态高度长列表,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!虚拟列表是一种根据滚动容器元素的可视区域来渲染长列表数据中某一个部分数据的技术。虚拟列表是对长

小编给大家分享一下如何使用React-virtualized实现图片动态高度长列表,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

虚拟列表是一种根据滚动容器元素的可视区域来渲染长列表数据中某一个部分数据的技术。虚拟列表是对长列表场景一种常见的优化,毕竟很少有人在列表中渲染上百个子元素,只需要在滚动条横向或纵向滚动时将可视区域内的元素渲染出即可。

开发中遇到的问题

长列表中的图片要保持原图片相同的比例,那纵向滚动在宽度不变的情况下,每张图片的高度就是动态的,当该列表项高度发生了变化,会影响该列表项及其之后所有列表项的位置信息。

图片width,height必须在图片加载完成后才能获得.

解决方案

我们使用react-virtualized中list组件,官方给出的例子

import React from 'react';import ReactDOM from 'react-dom';import {List} from 'react-virtualized';// List data as an array of stringsconst list = [  'Brian Vaughn',  // And so on...];function rowRenderer({  key, // Unique key within array of rows  index, // Index of row within collection  isScrolling, // The List is currently being scrolled  isVisible, // This row is visible within the List (eg it is not an overscanned row)  style, // Style object to be applied to row (to position it)}) {  return (    <div key={key} style={style}>      {list[index]}    </div>  );}// Render your listReactDOM.render(  <List    width={300}    height={300}    rowCount={list.length}    rowHeight={20}    rowRenderer={rowRenderer}  />,  document.getElementById('example'),);

如何使用react-virtualized实现图片动态高度长列表

其中rowHeight是每一行的高度,可以传入固定高度也可以传入function。每次子元素高度改变需要调用recomputeRowHeights方法,指定索引后重新计算行高度和偏移量。

具体实现

const ImgHeightComponent = ({ imgUrl, onHeightReady, height, width }) => {  const [style, setStyle] = useState({    height,    width,    display: 'block',  })  const getImgWithAndHeight = (url) => {    return new Promise((resolve, reject) => {      var img = new Image()      // 改变图片的src      img.src = url      let set = null      const onload = () => {        if (img.width || img.height) {          //图片加载完成          clearInterval(set)          resolve({ width: img.width, height: img.height })        }      }      set = setInterval(onload, 40)    })  }  useEffect(() => {    getImgWithAndHeight(imgUrl).then((size) => {      const currentHeight = size.height * (width / size.width)      setStyle({        height: currentHeight,        width: width,        display: 'block',      })      onHeightReady(currentHeight)    })  }, [])  return <img src={imgUrl} alt=''  style={style} />}

先写一个获取图片高度的组件,通过定时循环检测获取并计算出高度传给父组件。

import React, { useState, useEffect, useRef } from 'react'import styles from './index.sCSS'import { AutoSizer } from 'react-virtualized/dist/commonjs/AutoSizer'import { List  } from 'react-virtualized/dist/commonjs/List'export default class DocumentStudy extends React.Component {  constructor(props) {    super(props)    this.state = {      list: [],       heights: [],      autoWidth:900,      autoHeight: 300    }  }  handleHeightReady = (height, index) => {    this.setState(      (state) => {        const flag = state.heights.some((item) => item.index === index)        if (!flag) {          return {            heights: [              ...state.heights,              {                index,                height,              },            ],          }        }        return {          heights: state.heights,        }      },      () => {        this.listRef.recomputeRowHeights(index)      },    )  }  getRowHeight = ({ index }) => {    const row = this.state.heights.find((item) => item.index === index)    return row ? row.height : this.state.autoHeight  }  renderItem = ({ index, key, style }) => {    const { list, autoWidth, autoHeight } = this.state    if (this.state.heights.find((item) => item.index === index)) {      return (        <div key={key} style={style}>          <img src={list[index].imgUrl}  alt='' style={{width: '100%'}}/>        </div>      )    }    return (      <div key={key} style={style}>        <ImgHeightComponent          imgUrl={list[index].imgUrl}          width={autoWidth}          height={autoHeight}          onHeightReady={(height) => {            this.handleHeightReady(height, index)          }}        />      </div>    )  }  render() {    const { list } = this.state    return (      <>        <div style={{ height: 1000 }}>          <AutoSizer>            {({ width, height }) => (              <List                ref={(ref) => (this.listRef = ref)}                width={width}                height={height}                overscanRowCount={10}                rowCount={list.length}                rowRenderer={this.renderItem}                rowHeight={this.getRowHeight}              />            )}          </AutoSizer>        </div>      </>    )  }}

父组件通过handleHeightReady方法收集所有图片的高度,并在每一次高度改变调用List组件的recomputeRowHeights方法通知组件重新计算高度和偏移。到这里基本已经解决遇到的问题。

实际效果

如何使用react-virtualized实现图片动态高度长列表

目前只是使用react-virtualized来完成图片长列表实现,具体react-virtualized内部实现还需要进一步研究。

看完了这篇文章,相信你对“如何使用react-virtualized实现图片动态高度长列表”有了一定的了解,如果想了解更多相关知识,欢迎关注编程网精选频道,感谢各位的阅读!

--结束END--

本文标题: 如何使用react-virtualized实现图片动态高度长列表

本文链接: https://www.lsjlt.com/news/278415.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作