我想做以下事情:
firstModal
,其中包含提交表格。secondModal
并启动裁剪器以允许用户裁剪剪贴板粘贴图像的特定区域。这个问题有一些相似之处,但它没有提供确切的工作答案:CropperJS getCroppedCanvas()在第二次初始化时返回 null
下面是我现在所在的 html 和 js 代码。似乎第一次尝试工作正常,但是当我关闭模态并重复该过程时,
getCroppedCanvas
返回 null,这可能是什么原因?
替代 JsFiddle:https://jsfiddle.net/51sL06w9/1/
function checkFileUpload() {
var is_file = $("#isFile").is(":checked");
var is_ss = $("#isSS").is(":checked");
if (is_ss) {
$("#inputSS").prop("disabled", false);
$("#inputFile").prop("disabled", true);
} else {
$("#inputFile").prop("disabled", false);
$("#inputSS").prop("disabled", true);
document.getElementById("cropped-image").style.display = "none";
}
}
checkFileUpload();
$(document).on("click", "#isFile,#isSS", function(e) {
checkFileUpload();
});
const inputSS = document.getElementById("inputSS");
$(document).off("paste").on("paste", function(e) {
var clipboardData = e.clipboardData || window.clipboardData || e.originalEvent.clipboardData;
if ($("#isSS").is(":checked")) {
inputSS.files = clipboardData.files;
console.log("isSS checked and paste captured");
var $modal = $("#secondModal");
var cropper;
var image = document.querySelector("#cropper-image");
var files = inputSS.files;
var done = function(url) {
inputSS.value = "";
image.src = url;
$modal.modal("show");
};
var reader;
var file;
var url;
if (files && files.length > 0) {
file = files[0];
if (URL) {
done(URL.createObjectURL(file));
} else if (FileReader) {
reader = new FileReader();
reader.onload = function(e) {
done(reader.result);
};
reader.readAsDataURL(file);
}
}
$modal.on("shown.bs.modal", function() {
cropper = new Cropper(image, {
viewMode: 3,
});
}).on("hidden.bs.modal", function() {
cropper.destroy();
cropper = null;
});
$("#crop").on("click", function() {
var canvas;
console.log(cropper);
if (cropper) {
canvas = cropper.getCroppedCanvas({
width: 400,
height: 400,
});
console.log(canvas);
var resultImage = document.getElementById("cropped-image");
resultImage.src = canvas.toDataURL();
resultImage.style.display = "block";
canvas.toBlob(blob => {
const croppedFile = new File([blob], "croppedScreenShot.png");
const dT = new DataTransfer();
dT.items.add(croppedFile);
inputSS.files = dT.files;
});
}
$modal.modal("hide");
});
}
});
$("#firstModal").on("hidden.bs.modal", function() {
document.getElementById("submitForm").reset();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://fengyuanchen.github.io/cropperjs/js/cropper.js"></script>
<link href="https://fengyuanchen.github.io/cropperjs/css/cropper.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<button type="button" class="btn btn-warning" data-toggle="modal" data-target="#firstModal">Update</button>
<div id="firstModal" class="modal" tabindex="-1" role="dialog">
<form id="submitForm">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div id="firstModalBody" class="modal-body">
<div class="item form-group">
<label class="col-form-label col-md-3 col-sm-3 label-align">Document<span class="required">*</span></label>
<div id="s2File" class="col-md-9 col-sm-9">
<div class="nested-blocks">
<input type="radio" id="isFile" name="fileUploadRadio" value="1" class="form-radio" required="required" checked><label for="isFile">File Upload</label> <input type="file" id="inputFile" name="docFile" class="form-control has-feedback-left" value="" required>
</div>
<div class="nested-blocks">
<input type="radio" id="isSS" name="fileUploadRadio" value="1" class="form-radio"><label for="isSS">ScreenShot Paste</label> <input type="file" id="inputSS" name="docFile" class="form-control has-feedback-left" value="" disabled style="background-color:#e9ecef;pointer-events:none">
</div>
<img id="cropped-image" src="" alt="SS" style="display:none;margin-top:10px;max-width:500px;max-height:200px">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary">Submit</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</form>
</div>
<div id="secondModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="img-container"><img id="cropper-image" src="" alt="SS"></div>
</div>
<div class="modal-footer">
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="crop">Crop</button>
</div>
</div>
</div>
</div>
</div>
我认为你的 JavaScript 代码是用 ajax 内容加载的(ajax 带来了 DOM),而不是在父 DOM 上。当您在动态 ajax 加载的内容上使用 JavaScript 时,您需要确保在模式关闭时卸载事件,以避免堆叠事件执行。
我检查了你的代码,你使用了委托事件,但是当你关闭模态时你没有卸载它们。因此,在第一次模态关闭时,cropper 为 null,当您启动第二轮时,js 事件将被堆叠,并运行两次并导致 canvas 返回 null。 解决方案:
$(document).off("click", "#isFile,#isSS");
$(document).off("paste", "#firstModalBody");
#crop
上的点击事件,同样您还需要取消绑定显示/隐藏事件:$modal.unbind("shown.bs.modal");
和 $modal.unbind("hidden.bs.modal");