admin管理员组

文章数量:1295928

The method is called in the ready event. On the first call it works. When the modal is closed, I am destroying the cropper - cropper.destroy() . After opening the modal second time, the cropper is initialized again but this time cropper.getCroppedCanvas() returns null

let cropper = new Cropper(image, {
                dragMode: 'move',
                aspectRatio: ratio,
                restore: false,
                guides: false,
                center: false,
                highlight: false,
                cropBoxMovable: false,
                cropBoxResizable: false,
                toggleDragModeOnDblclick: false,
                ready: function () {

                    modal.find(".save").on("click", function () {
                        console.log(cropper.getCroppedCanvas())
                        cropper.getCroppedCanvas().toBlob(function (blob) {
                            let formData = new FormData()
                            formData.append("croppedImage", blob)

                            jQuery.ajax({
                                method: "post",
                                url: "index.php?option=_image_slideshows&task=slideshow.saveCroppedImage",
                                data: formData,
                                processData: false,
                                contentType: false
                            })
                            .done(function (response) {
                                modal.modal("hide")
                            })
                        })
                    })

                    cropper.crop()
                }
            })

On modal closing this happens:

modal.on("hidden.bs.modal", function () {
                cropper.destroy()
                jQuery("#cropper-modal .modal-body").html(
                    jQuery("<img>", {
                        id: "image",
                        "class": "cropper-hidden"
                    })
                )

            })

The method is called in the ready event. On the first call it works. When the modal is closed, I am destroying the cropper - cropper.destroy() . After opening the modal second time, the cropper is initialized again but this time cropper.getCroppedCanvas() returns null

let cropper = new Cropper(image, {
                dragMode: 'move',
                aspectRatio: ratio,
                restore: false,
                guides: false,
                center: false,
                highlight: false,
                cropBoxMovable: false,
                cropBoxResizable: false,
                toggleDragModeOnDblclick: false,
                ready: function () {

                    modal.find(".save").on("click", function () {
                        console.log(cropper.getCroppedCanvas())
                        cropper.getCroppedCanvas().toBlob(function (blob) {
                            let formData = new FormData()
                            formData.append("croppedImage", blob)

                            jQuery.ajax({
                                method: "post",
                                url: "index.php?option=_image_slideshows&task=slideshow.saveCroppedImage",
                                data: formData,
                                processData: false,
                                contentType: false
                            })
                            .done(function (response) {
                                modal.modal("hide")
                            })
                        })
                    })

                    cropper.crop()
                }
            })

On modal closing this happens:

modal.on("hidden.bs.modal", function () {
                cropper.destroy()
                jQuery("#cropper-modal .modal-body").html(
                    jQuery("<img>", {
                        id: "image",
                        "class": "cropper-hidden"
                    })
                )

            })
Share Improve this question asked Dec 1, 2019 at 20:41 Toma TomovToma Tomov 1,70426 silver badges67 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 6 +25

My guess would be that the cropper variable you set initially:

let cropper = new Cropper(...)

is still being referenced in your ready function the second time around. I would first try ensuring that the cropper variable is set to null after cropper.destroy() is called.

You could also try accessing the correct Cropper instance in your ready function by accessing this.cropper, for example:

ready: function () {
  modal.find(".save").on("click", function () {
    console.log(this.cropper.getCroppedCanvas());
  }
}

Besides calling destroy() method you also need to reinitialize the event listeners.

I think that event listeners still hold a reference to the old cropper so you need to unbind() them first and create them again on every ready() function call. I also suggest using this pointer instead of variable cropper to ensure you access the current instance.

ready: function () {
  var that = this;
  modal.find(".save").unbind('click');
  modal.find(".save").on("click", function () {
    console.log(that.cropper.getCroppedCanvas());
  }
}

@jmfolds is correct, it is important that you reference this.cropper.

However, that is not enough. You have to verify that the cropper is ready for the second cropping instance even if the function is defined in the "ready" event of the cropper and assuming that the first cropper is destroyed. You can do that easily using an if statement:

if (this.cropper.ready === true) {
    // Your code as is
} else {
    return
}

This solved my problem when I was implementing it.

In your destroy function do you remove the .on event too?

modal.find(".save").off(); 

After the cropper.destroy(); did you validate that it is really destroyed? maybe set in the variable cropper too null or undefined too after destroy.

So my 2 cents, It looks all correct so far I see.

本文标签: javascriptCropperJS getCroppedCanvas() returns null on second initializationStack Overflow