DOMおれおれAdvent Calendar 2015 – 22日目

2015-12-22

jQueryなら $el.trigger('foo') とするだけで簡単なんだけど、DOMでやるとちょっと面倒くさいです。

独自イベントを作る

CustomEventというコンストラクターを使います。第一引数にイベント名を与えます。

var type = 'foo';
var myEvent = new CustomEvent(type);

console.log(myEvent, myEvent.type);

基本的にこれで良いのだけど、IEはエラーになります。しかもCustomEventコンストラクターはあるのに使っちゃ駄目っていう仕様です。(だから有無だけじゃ判断できない。) IEてそういうところあるよね……。

というわけで

仕方ないからIEでも動くやり方にします。

var type = 'foo';
var myEvent = document.createEvent('CustomEvent');
myEvent.initCustomEvent(type, false, false, null);

console.log(myEvent, myEvent.type);

IEでも動くんならこれでいいんじゃ?

と思う方もおられるかと思いますが、なんでもこっちのやり方は廃止の予定だそうで。 new CustomEvent() の方を使ってね、だそうです。

イベントに情報を持たせる

CustomEventの場合、 event.detail で参照できる情報を設定する事ができます。

var type = 'foo';
var detail = { sushi:'tuna' };

var event1 = document.createEvent('CustomEvent');
event1.initCustomEvent(type, false, false, detail);
console.log(event1.detail.sushi);  // => "tuna"

var event2 = new CustomEvent(type, { detail:detail });
console.log(event2.detail.sushi);  // => "tuna"

本物?のイベントの見分け方

ユーザー操作からウェブブラウザーが生成した本物のイベントは、 isTrusted プロパティが true になります。JavaScriptから生成した場合はこれが false になるので、ここを見ると「あ、こいつ騙りだ!」と分かります。

クリックイベントを作る

引数が多くて割と面倒くさい。

var event = document.createEvent('MouseEvents');
event.initMouseEvent('click',
  true,    // bubbles
  true,    // cancelable
  window,  // view
  null,    // detail
  0,       // screenX
  0,       // screenY
  0,       // clientX
  0,       // clientY
  false,   // ctrlKey
  false,   // altKey
  false,   // shiftKey
  false,   // metaKey
  0,       // button
  null     // relatedTarget
);

IEを捨てられるなら new MouseEvent('click') だけで事足ります。情報を与える必要がある場合は第二引数にオブジェクトを指定します。

var event = new MouseEvent('click', {
  bubbles: true,
  button: 1
});

イベントを発火させる

dispatchEvent() でイベントを発火させる事ができます。

// eventは作成済みとします

var el = document.querySelector('#el');

el.addEventListener('click', function(event) {
  console.log(event.type);
});

el.dispatchEvent(event);

上記の例の通り、イベントは普通に addEventListener() で監視できます。ちなみに監視はあくまでイベント名を対象に行うので、MouseEventでもCustomEventでも、 type が "click" であれば反応します。

ちなみにjQuery

jQueryはjQuery.Eventという独自のコンストラクターを用意して、DOMのイベントとは無関係にやってるみたいです。なので本来の event にあるはずのプロパティがなかったりする。

元のイベントは event.originalEvent に格納されるので、適宜そちらを利用します。携帯端末のタップ関係とかこっち使うね。

参考