IEでテキストをinput[text]・textareaにDragDropした時、ng-modelが更新されない
AngularJSを使った開発で、FireFox、Chromeでは問題なく動作して、いつものごとくIE11で動作しなかった現象が発生
やりたいことは、テキストボックス(またはテキストエリア)の文字数のカウントを取りたいだけ
特に複雑なコードではなく、$scope.$watchでng-modelが変わった時に、文字数をカウントをするようなコードを書いた
普通にキーボードからの入力では問題なく動作したが、以下の手順でIE11では動かなかった。
テキストを選択した状態(メモ帳、htmlのテキストエリアなど)にする。
選択状態のテキストをマウスドラッグする。
ドラッグ中のテキストを、貼り付けたいテキストエリアにドロップする。
テキスト自体はちゃんと貼り付けられているが、内部(ng-model)が更新されていない様子。フォーカスが別の場所に移るとng-modelが更新され、$scope.$watchのコールバック関数が動作している感じ
考え中・・・
テキストが入力確定するタイミング(イベント)が謎
AngularJSの対象外のイベントが発生している?
もしやIE11の独自実装イベント!?
正直良くわからないので、DragDropでテキストコピーした時に発生しているイベントを虱潰しに調べてみた。(textareaのプロパティの「on●●●」全部を、ログ出力関数で全部bindしてやりゃー)
Chrome、IE11両方とも発生するイベントは同じ。
↓関係ありそうなイベント
ondropover・・・選択状態のテキストをマウスドラッグして、textareaの上に重ねた状態で常に発生
ondrop、oninput・・・ドラッグ中のテキストを、貼り付けたいテキストエリアにドロップしたときに発生(Chrome、IE11ともにondropが先)
重要なイベントは「ondrop、oninput」みたい。
ということは、「onclick→ng-click」みたいな感覚で「ondrop→ng-drop」、「oninput→ng-input」ディレクティブがあって、それらを使えばいいんじゃ!?
・・・ありませんでした。\(^o^)/
英語のサイトで「これで要素がマウスで『ぐるんぐるん』出来るよ!」みたいなサイトばかり見つかる
絶対に違う気がする・・・
私好みの「ondrop→ng-drop」、「oninput→ng-input」がないなら作るしかない・・・
というわけで、いろいろ参考にしつつ出来たのがコチラ(IEじゃないと特に動作の違いなし)↓*1 *2
「ngDropCopy」がIE11で、DragDropに対応するためのディレクティブ
「oninput」と「onpropertychange」のイベント登録し、発火した時にng-modelを更新するようにした。
onpropertychangeは古いIE用。「oninput」は古いIEは対応していないらしい *3
「ondrop」を使用していない理由は、IE11の場合「textarea」から値が取得できなかったため。
ちなみにFireFox、Chromeだと、「ngDropCopy」を使用すると「oninput」・「ondrop」で$scope.$watchが2回動作してしまう。
やりたいことが文字数のカウントだから2回動作しても問題ないので気にしない(´ε` )