Ash
Ash

Reputation: 141

HTML <p> element text update problem when updating it through <Input> element onchange event

Here is a simple reproducible code of the issue I'm worried about

<!DOCTYPE html>
<html lang="en">

<head>
  <title>Test</title>
  <h1>Testing</h1>
  <script type="text/javascript">
    function readImg() {
      var reader = new FileReader();
      reader.readAsDataURL(document.getElementById("srcImg").files[0]);

      reader.onload = function(readerEvent) {
        document.getElementById("previewImage").src = readerEvent.target.result;
      };
      /*set uploaded image dimension to imgDims*/
      document.getElementById("imgDims").innerHTML = document.getElementById("previewImage").naturalWidth;
    }
  </script>
</head>

<body>
  <input type="file" id="srcImg" name="srcImg" onchange="readImg()"><br>
  <img id="previewImage"><br>
  <p id="imgDims">test</p> <! display uploaded image dimension here >
</body>

</html>

When I upload an image for the first time, 'imgDims' shows 0. Uploading an image for the second time, 'imgDims' now shows the first time image's width. And uploading image for the third time, 'imgDims' shows the second time image's width and so on.

My intent here is to display the current uploaded image's dimensions under the previewImage html element

really confused as to what really the problem here is, any help?

Upvotes: 0

Views: 65

Answers (1)

Endless
Endless

Reputation: 37815

The problem is that you print the dimention before the image is loaded

    function readImg() {
      var reader = new FileReader();
      reader.readAsDataURL(document.getElementById("srcImg").files[0]);

      reader.onload = function(readerEvent) {
        document.getElementById("previewImage").src = readerEvent.target.result;
      };
      // this is wrong
      document.getElementById("imgDims").innerHTML = document.getElementById("previewImage").naturalWidth;
    }

should be

    function readImg() {
      var reader = new FileReader();
      reader.readAsDataURL(document.getElementById("srcImg").files[0]);

      reader.onload = function(readerEvent) {
        document.getElementById("previewImage").src = readerEvent.target.result;
        document.getElementById("imgDims").innerHTML = document.getElementById("previewImage").naturalWidth;
      };
      
    }

fyi, using the filereader to load the image as a base64 is a waste of time encoding/decoding binary to and from base64. If you use a objectURL then you can load the binary faster

Here is how what you can do instead:

  <input type="file" id="srcImg" name="srcImg" onchange="readImg()"><br>
  <img id="previewImage"><br>
  <p id="imgDims">test</p> <! display uploaded image dimension here >

  <script>
    const [input, img, imgDims] = 
      document.querySelectorAll('#srcImg, #previewImage, #imgDims')

    img.onload = () => {
      imgDims.innerText = `${img.width} x ${img.height}`
    }

    function readImg() {
      img.src = URL.createObjectURL(input.files[0])
    }
  </script>

Upvotes: 1

Related Questions