質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

2423閲覧

JavaScriptでイベントが2回走ってしまう

yamaotakuro

総合スコア13

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2020/09/10 11:43

Cropper.jsを使用し画像ファイルのトリミングをしたあとサーバーにアップするという処理を行うスクリプトを書いています。
https://fengyuanchen.github.io/cropperjs/
1回目は問題なく処理されるのですが2回目以降はトリミングが複数回行われてしまいます。
2回目は2回、3回目は3回となります。

該当部分のコード

javascript

1let cropper; 2const imageUpload = (blob)=>{ 3 4 // 画像要素の生成 5 const image = new Image(); 6 7 // File/BlobオブジェクトにアクセスできるURLを生成 8 const blobURL = URL.createObjectURL(blob); 9 10 //元データのContent-Typeをいれとく 11 const contentType = blob.type; 12 13 // src にURLを入れる 14 image.src = blobURL; 15 image.id = 'js-crop_target'; 16 17 const aspectBtn = document.querySelectorAll('.js-aspect_btn'); 18 const aspectBtnArr = Array.prototype.slice.call(aspectBtn,0); 19 20 21 document.querySelector('.upload_in').style.display = 'none'; 22 document.querySelector('.js-upload_control').style.display = 'flex'; 23 24 // #output へ出力 25 output.appendChild(image); 26 const cropTarget = document.getElementById('js-crop_target'); 27 28 //Cropper用のオプション 29 let options = { 30 aspectRatio: 16 / 9, 31 viewMode:2 32 }; 33 34 //Cropperインスタンスを生成 35 cropper = new Cropper(cropTarget, options); 36 37 //アスペクト比を変更した場合 38 aspectBtnArr.forEach(function (target) { 39 target.addEventListener('change', function (event) { 40 41 let options = { 42 aspectRatio: event.target.value, 43 viewMode:2 44 }; 45 46 cropper.destroy(); 47 cropper = new Cropper(cropTarget, options); 48 }); 49 }); 50 51 const trim = ()=>{ 52 console.log(cropper.getCroppedCanvas() + '111'); 53 const result = cropper.getCroppedCanvas().toDataURL(); 54 cropTarget.setAttribute('src',result); 55 cropper.clear(); 56 cropper.destroy(); 57 } 58 59 const upload = ()=>{ 60 const formData = new FormData(); 61 formData.append('name', 'crop_img-' + new Date().getTime()) 62 formData.append('file', blob) 63 formData.append('content-type', contentType) 64 65 document.querySelector('.upload_in').style.display = 'block'; 66 document.querySelector('.js-upload_control').style.display = 'none'; 67 68 69 //POST処理 70 axios.post('/admin/media/post', formData) 71 .then(response => { 72 console.log(response) 73 // output.querySelector('img').remove(); 74 closeModal(); 75 cropper.destroy(); 76 console.log(cropper); 77 document.querySelector('.js-upload_trg').removeEventListener('click',trim,true); 78 document.querySelector('.js-triming_trg').removeEventListener('click',upload,true); 79 80 }) 81 .catch(function (error) { 82 console.log(error) 83 // output.querySelector('img').remove(); 84 closeModal(); 85 cropper.destroy(); 86 console.log(cropper); 87 }) 88 } 89 90 //ファイルをアップロード 91 document.querySelector('.js-upload_trg').addEventListener('click', upload,true); 92 93 //トリミング 94 document.querySelector('.js-triming_trg').addEventListener('click', trim,true); 95 96 }

##試したこと

  • イベントを削除する必要があると思ったのでremoveEventListenerをpost処理の後に入れてみたが効果なし
  • cropperインスタンスがdestroyできず残っているかと思いundefinedを入れてみたりしたが効果なし

##コンソールでの表示
イメージ説明

まだサーバーサイドのPOST処理は出来ていないので無視してください。

2回目のクロップ時にCanvasオブジェクトがnullになります(これはdestoryしたからですが)
2回処理が行われる原因がわかりません。

なにか良い方法をご教授いただけると幸いです。
よろしく願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

自己解決しました。
イベントの削除は最後にと思ってaxiosのレスポンス後にしてたのですがどうも効いていないようなので
関数の最後にremoveEventListenerを記述すると動作しました。

なぜレスポンス後にremoveEventListenerすると効かないのか謎は残りましたがひとまず解決致しました。
回答いただいた方本当にありがとうございました。

投稿2020/09/11 01:06

yamaotakuro

総合スコア13

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

document.querySelector('.js-upload_trg').removeEventListenerに渡すのはtrimではなくuploadではないでしょうか。(その下の行も同様に確認してみてください。)

投稿2020/09/10 12:13

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yamaotakuro

2020/09/11 00:55

ありがとうございます。 間違えてました! しかし変更しても変わらずです。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問