0

I found a piece of code that changes the img on display once you get a file for a preview. I understand everything except for the meaning of oFREvent. I've searched it up and have seen other people using it but can't find what it does. Is there an effect that it has that differs from anything else that could be there?

        let oFReader = new FileReader();
        oFReader.readAsDataURL(document.getElementById("uploadImage").files[0]);

        oFReader.onload = function (oFREvent) {
            document.getElementById("uploadPreview").src = oFREvent.target.result;
        };
    };

This is the html for the function

<input type="text" name="imgName"><br>
<input id="uploadImage" type="file" name="newImg" onchange="PreviewImage();">
  • `oFREvent` is shorthand form `fileReaderEvent`. `FileReader` puts to callback function it when finished loading image as base64 string in this case. More [here](https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL) – capchuck Sep 08 '21 at 05:07
  • You probably shouldn't be using `readAsDataURL` to load an `img`: **it's sloooooww**. Instead use `URL.createObjectUrl` which is _much faster_: https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL – Dai Sep 08 '21 at 05:17

1 Answers1

0
  • In the JavaScript world, all event-handler functions should accept an Event object as the first function argument.
    • An event-handler function is a function specified as the callback for addEventListener and/or directly assigning to the (legacy) onclick-style function-properties (such as onload, onunload, onclick, etc).
    • Note that as of 2021, you should not use the onclick-style function-properties anymore, instead you should always prefer addEventListener).
  • Each specific event in the DOM, such as a <button>'s HTMLButtonElement's click event, has its own additional data (such as indicating which mouse button was clicked, or which keyboard key was pressed) which is passed via this Event object as subclass data
  • Similarly, FileReader has a load event which is fired when it loads the File object specified (this happens asynchronously, instead of all in readAsDataURL) because reading a file can take seconds or even minutes, and would otherwise block the script, which in-turn would block the web-page's UI thread.
    • FileReader's load event uses ProgressEvent for its Event subclass. This is the same Event subclass used by FileReader's loadstart, loadend and progress events, so you can use the same event-handling code for all events if you're only updating a progress indicator.
  • In this case, the onload handler doesn't need to check the ProgressEvent object because the onload handler will only be invoked after the data is successfully fully loaded.
    • That said, there's at least 3 things wrong with the code you posted - I don't recommend using it in production at all.

I recommend using this code instead, fwiw:

  • You don't need to use FileReader at all.
  • Just pass the selected File (from files[0]) into URL.createObjectURL and use that URL as the .src for your <img />.
function onFileSelected() {
    
    const fileReader = new FileReader();
    const file       = document.getElementById("uploadImage").files[0];
    if( !file ) return;

    const objectUrl = URL.createObjectURL( file );
    document.getElementById("uploadPreview").src = objectUrl;

    if( window.lastObjectUrl ) {
        // This step is necessary to release the _previous_ objectURL (if any) to prevent leaking memory.
        URL.revokeObjectURL( window.lastObjectUrl );
    }

    window.lastObjectUrl = objectUrl;
}
Dai
  • 141,631
  • 28
  • 261
  • 374