0

I am displaying an image on React web app.

My code is like below:

<img
    alt={fileName}
    onLoad={onLoad}
    src={url}
/>

I want to display an indicator around the image, which tells user about the image download percentage.

I know with onLoad property is to provide a function which will be called when image finishes loading, but I don't know how to detect the image downloading percentage (or downloaded size).

Is there a property like onLoad? I tried onProgress but it didn't get fired.

I've read this question JavaScript loading progress of an image.

But the highest vote answer in this question doesn't answer my question.

That answer needs to create a new Image() instance manually, what I want is to know whether there is a built-in support for onProgress property, or please advise how to build a lower mechanism to support this.

LiuWenbin_NO.
  • 1,216
  • 1
  • 16
  • 25
  • Possible duplicate of [JavaScript loading progress of an image](https://stackoverflow.com/questions/14218607/javascript-loading-progress-of-an-image) – Agney Jun 03 '19 at 09:18
  • @BoyWithSilverWings, I edited the question and added the explanation for answers in that question don't resolve my problem. Thanks. – LiuWenbin_NO. Jun 03 '19 at 09:27
  • No, there is no native support for this. – Agney Jun 03 '19 at 10:22
  • @BoyWithSilverWings Thanks for the info. Any advice if I want to add such a custom property to `img` tag? – LiuWenbin_NO. Jun 03 '19 at 13:02

1 Answers1

1

I try to use onProgress built in property in img tag jsx but in doesn't work, not sure why it is exclusive for audio or video

So I create my own way to get the percentage of image by manually fetching it as arrrayBuffer in XMLHttpRequest, and here how it looks like

...
componentDidMount(): void {
  const {src, onProgress, onLoadStart, onLoadEnd} = this.props;

  if (onProgress || onLoadStar || onLoadEnd) {
    this.renderImage(src);
    return;
  }

  this.setState({src});
}

renderImage = (src: string) => {
  const {onProgress, onLoadStart, onLoadEnd} = this.props;
  const request = new XMLHttpRequest();
  request.responseType = 'arraybuffer';
  request.open('GET', src, true);
  request.onprogress = function (e) {
    const loadPercentage = Math.floor((e.loaded / e.total) * 100);
    onProgress && onProgress(loadPercentage);
  };
  request.onloadstart = () => {
    onLoadStart && onLoadStart();
  };
  request.onloadend = () => {
    const blob = new Blob([request.response]);
    const source = window.URL.createObjectURL(blob);
    this.setState({src: source});

    onLoadEnd && onLoadEnd();
  };
  request.send();
};

render(): ReactNode {
  return <img src={this.state.src}/>
}
...
Marvin
  • 647
  • 7
  • 15