1
votes

Trying to upload an image file with preview using Jquery. It's working and I got the preview, but when I click on the upload button I saw an error message

Uncaught RangeError: Maximum call stack size exceeded

in the console.


Here is the code:

$(document).ready(function() {
  var readURL = function(input) {
    if (input.files && input.files[0]) {
      var reader = new FileReader();
      reader.onload = function(e) {
        $('.profile-image').attr('src', e.target.result);
      }
      reader.readAsDataURL(input.files[0]);
    }
  }

  $(".file-upload").on('change', function() {
    readURL(this);
  });

  $(".upload-button").on('click', function() {
    $(".file-upload").click();
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

  <img class="profile-image" src="demo.png" alt="Profile Image">
  <a class="profile-img-edit upload-button">
    <i class="fas fa-camera"></i> Select Image
    <input class="file-upload" type="file" name="file" size="40" accept=".png, .jpg, .jpeg, .gif">
  </a>
</div>
1

1 Answers

2
votes

The issue is because the click event on the .file-upload element bubbles up to .upload-button and is caught by the click handler, which triggers a click handler on .file-upload which bubbles up to .upload-button which triggers a click... and so on.

To fix this, stop the event from bubbling up from the .file-upload by adding a click event handler to it and calling stopPropagation() on the event, like this:

$(document).ready(function() {
  var readURL = function(input) {
    if (input.files && input.files[0]) {
      var reader = new FileReader();
      reader.onload = function(e) {
        $('.profile-image').attr('src', e.target.result);
      }
      reader.readAsDataURL(input.files[0]);
    }
  }

  $(".file-upload").on('change click', function(e) {
    e.stopPropagation();
    readURL(this);
  });

  $(".upload-button").on('click', function() { 
    $(".file-upload").click();
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

  <img class="profile-image" src="demo.png" alt="Profile Image">
  <a class="profile-img-edit upload-button">
    <i class="fas fa-camera"></i> Select Image
    <input class="file-upload" type="file" name="file" size="40" accept=".png, .jpg, .jpeg, .gif">
  </a>
</div>