読者です 読者をやめる 読者になる 読者になる

もなかアイスの試食品

「とりあえずやってみたい」そんな気持ちが先走りすぎて挫折が多い私のメモ書きみたいなものです.

IEでテキストをinput[text]・textareaにDragDropした時、ng-modelが更新されない

AngularJSを使った開発で、FireFoxChromeでは問題なく動作して、いつものごとくIE11で動作しなかった現象が発生

やりたいことは、テキストボックス(またはテキストエリア)の文字数のカウントを取りたいだけ

特に複雑なコードではなく、$scope.$watchでng-modelが変わった時に、文字数をカウントをするようなコードを書いた

普通にキーボードからの入力では問題なく動作したが、以下の手順でIE11では動かなかった。

  1. テキストを選択した状態(メモ帳、htmlのテキストエリアなど)にする。

  2. 選択状態のテキストをマウスドラッグする。

  3. ドラッグ中のテキストを、貼り付けたいテキストエリアにドロップする。

テキスト自体はちゃんと貼り付けられているが、内部(ng-model)が更新されていない様子。フォーカスが別の場所に移るとng-modelが更新され、$scope.$watchのコールバック関数が動作している感じ


考え中・・・

  • テキストが入力確定するタイミング(イベント)が謎

  • AngularJSの対象外のイベントが発生している?

  • FireFoxChromeでは問題なく動作している理由は?

  • もしや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」から値が取得できなかったため。

ちなみにFireFoxChromeだと、「ngDropCopy」を使用すると「oninput」・「ondrop」で$scope.$watchが2回動作してしまう。

やりたいことが文字数のカウントだから2回動作しても問題ないので気にしない(´ε` )