为什么#btnCrop 上的 "mouseup" 事件不止一次触发?

Why "mouseup" event on #btnCrop triggers more than once?

Cropper.js 适用于第一张图片。当我上传一张新图片然后裁剪它时,#result 附加了两张图片。对于第三张上传的图片,#result 附加了三张(!)图片。我自己弄不明白为什么每次上传新图片时这个函数 ($("#btnCrop").on("mouseup", function()) 执行得越来越多。有什么想法吗?

<div id="cropper" class="field personalization">
  <div class="field-input">
    <div class="radioOptions">
      <div class="radio">
        <input type="radio" id="locket-upload" value="locket-upload" name="personalization"/>  
        <label for="locket-upload">Locket Photo</label>
      </div>
    </div>
  </div>
  <div class="reveal-if-active" id="reveal-if-active-locket-upload">
    <p class="line-item-property__field">
      <input type="file" id="fileInput" accept="image/*" />
      <div id="abrakadabra" class="image-container">
        <img id="ifc" src="#" alt="your image" />
      </div>
      <div id="result"></div>
      <div class="buttons-container">
        <input type="button" id="btnCrop" value="Crop" />
        <input type="button" id="btnDestroy" value="Upload new Image" />
      </div>   
    </p>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.1/cropper.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-cropper@1.0.0/dist/jquery-cropper.js"></script>
<link  href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.1/cropper.css" rel="stylesheet">
<script>
  $(document).ready(function(){
    var image = $('#ifc');
    var result = $('#result');
    var counter = 0;
    $("#fileInput").on("input", function(){
      if (this.files && this.files[0]) {
        var reader = new FileReader();
        reader.onload = function (e) {
          image.attr('src', e.target.result);
          $("#abrakadabra").css("display", "block");
          $(".buttons-container").css("display", "flex"); 

          var cropper = image.cropper({
            aspectRatio: Math.sqrt(3)/2,
            viewMode: 2,
            dragMode: 'move'
          });

          $("#btnCrop").on("mouseup", function(){
            var croppedImageDataURL = image.cropper('getCroppedCanvas', 'maxWidth: 300', 'fillColor: #fff').toDataURL("image/png");
            $("#abrakadabra").css("display", "none");
            $('#result').append( $('<img>').attr('src', croppedImageDataURL) );
          });  

          $("#btnDestroy").on("mouseup", function(){
            image.attr('src', "#");
            image.cropper('destroy');
            result.empty();
            $("#fileInput").val("");
            $("#abrakadabra, .buttons-container").css("display", "none");
            $('html, body').animate({scrollTop: ($("#fileInput").offset().top - 150)}, 500);
          });  
        };
        reader.readAsDataURL(this.files[0]);
      }
    });
  });
</script>

问题是每次你select一张图片,你发现点击事件到$("#btnCrop")。这就是它运行多次的原因。

解决方法是将点击事件移出。看下面的代码。

$(document).ready(function() {
  var image = $('#ifc');
  var result = $('#result');
  var counter = 0;
  $("#fileInput").on("input", function() {
    if (this.files && this.files[0]) {
      var reader = new FileReader();
      reader.onload = function(e) {
        image.attr('src', e.target.result);
        $("#abrakadabra").css("display", "block");
        $(".buttons-container").css("display", "flex");

        var cropper = image.cropper({
          aspectRatio: Math.sqrt(3) / 2,
          viewMode: 2,
          dragMode: 'move'
        });


      };
      reader.readAsDataURL(this.files[0]);
    }
  });

  $("#btnCrop").on("mouseup", function() {
    console.log("CROP")
    var croppedImageDataURL = image.cropper('getCroppedCanvas', 'maxWidth: 300', 'fillColor: #fff').toDataURL("image/png");
    $("#abrakadabra").css("display", "none");
    $('#result').append($('<img>').attr('src', croppedImageDataURL));
  });

  $("#btnDestroy").on("mouseup", function() {
    image.attr('src', "#");
    image.cropper('destroy');
    result.empty();
    $("#fileInput").val("");
    $("#abrakadabra, .buttons-container").css("display", "none");
    $('html, body').animate({
      scrollTop: ($("#fileInput").offset().top - 150)
    }, 500);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="cropper" class="field personalization">
  <div class="field-input">
    <div class="radioOptions">
      <div class="radio">
        <input type="radio" id="locket-upload" value="locket-upload" name="personalization" />
        <label for="locket-upload">Locket Photo</label>
      </div>
    </div>
  </div>
  <div class="reveal-if-active" id="reveal-if-active-locket-upload">
    <p class="line-item-property__field">
      <input type="file" id="fileInput" accept="image/*" />
      <div id="abrakadabra" class="image-container">
        <img id="ifc" src="#" alt="your image" />
      </div>
      <div id="result"></div>
      <div class="buttons-container">
        <input type="button" id="btnCrop" value="Crop" />
        <input type="button" id="btnDestroy" value="Upload new Image" />
      </div>
    </p>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.1/cropper.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-cropper@1.0.0/dist/jquery-cropper.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.1/cropper.css" rel="stylesheet">