プリロード処理が完了したときにイベントを発行したいとかEVENT.COMPLETE
dom要素の高さが確定したときにイベントを発行したいとかEVENT.HEIGHT_FIXED
顔認識で対象を検出したときにイベントを発行したいとかEVENT.DETECTED
使い所の多いカスタムイベントのまとめ。
(イベント名は仮です)
EventEmitter
cdnで読み込む(node.jsなら不要)
https://cdnjs.com/libraries/EventEmitter
デモ:http://codepen.io/mo4_9/pen/ZOVEWW
<script src="https://cdnjs.cloudflare.com/ajax/libs/EventEmitter/5.1.0/EventEmitter.min.js"></script>
var eventEmitter = new EventEmitter();
// 必ずしもEVENTオブジェクトをつくる必要はないが、
// カスタムイベントであることがわかりやすいのでオススメ
var EVENT = {
DETECTED: 'detected',
COMPLETE: 'complete'
};
// Listen for the event.
eventEmitter.on(EVENT.DETECTED, () => {
console.log('DETECTED 発火!');
});
eventEmitter.on(EVENT.COMPLETE, () => {
console.log('COMPLETE 発火!');
});
// Dispatch the event.
setTimeout(() => {
eventEmitter.emit(EVENT.DETECTED);
}, 1000);
setTimeout(() => {
eventEmitter.emit(EVENT.COMPLETE);
}, 3000);
応用例:【祝!リニューアル】カヤック 新コーポレートサイト、5種類テーマ切り替えの裏側!【フロントエンド芸】
こちらの応用例を元に書いた記事
http://qiita.com/mo4_9/items/4c12ad835b329ddc663c
JavaScript | dispatchEvent
var event = new Event('build');
// Listen for the event.
elem.addEventListener('build', function (e) { ... }, false);
// Dispatch the event.
elem.dispatchEvent(event);
以下の記事のようにクラス内部でイベントを発行して、外部に持ち出してあげるのが良い使い方。依存関係をなくせるのが利点。
javascriptでEventDispatcherを使うときのメモ
jQuery | trigger
const $dispatcher = $({});
// Listen
$dispatcher.on('complete', e => { ... });
// Dispatch
setTimeout( () => {
$dispatcher.trigger('complete');
}, 1000);
使用例:プリロード
http://codepen.io/mo4_9/pen/VjqRqd
使用例:カウンターとポップアップ
http://codepen.io/mo4_9/pen/RREGwO
カウンターが7の倍数の時にポップアップを表示する。
カウンターとポップアップの機能は独立させたいので、別々にクラスをつくる。カウンターにDOMイベントを登録して、その中でポップアップのメソッドを実行する。
jQuery.callbacks()
DOMに紐付かないのに無駄にカスタムイベントを使ったり、Ajax通信でdone()やresolve()しか呼び出さないのに無駄にDeferredを使うくらいなら、jQuery.callbacks()
を使ったほうがいいという認識が多い。
単純に任意のタイミングで関数を実行したいときに使える。オプション指定で実行制御も可能。
function hoge () {
console.log("hoge");
}
function piyo () {
console.log("piyo");
}
// コールバックオブジェクトを作成
const callbacks = $.Callbacks();
// コールバックに関数を登録
callbacks.add(hoge);
callbacks.add(piyo);
// 実行
callbacks.fire();
'hoge'
'piyo'
参考
https://api.jquery.com/jQuery.Callbacks/
http://www.jquerystudy.info/reference/callbacks/callbacks.html
Pub/Sub
デザパタ(オブザーバ)の一種Pub/Sub(パブリッシュ/サブスクライブ)
カスタムイベントの応用形みたいなニュアンス
上記のjQuery.callbacks()
もPub/Subだし、大きく分けるとカスタムイベントもPub/Subに含まれるという考えもあるが、まあ実務で支障なく使えればいい。
フロントエンドjavascriptのpubsubパターンとカスタムイベントの違い・使い分け
pubsub-jsのサンプル
import $ from 'jquery';
import PubSub from 'pubsub-js';
export default class Topic1 {
constructor(opts = {}) {
this.TOPIC_NAME = 'TOPIC1';
this.init();
}
init() {
const $btn1 = $('.btn').eq(0);
$btn1.on('click', () => {
// 発行
PubSub.publish(`btnClick.${this.TOPIC_NAME}`, `hello world, ${this.TOPIC_NAME}`);
})
}
}
import PubSub from 'pubsub-js';
import Topic1 from './Topic1';
// 購読
PubSub.subscribe( 'btnClick.TOPIC1', mySubscriber );
function mySubscriber ( msg, data ) {
console.log(`msg : ${msg}`, `data : ${data}`);
// msg : btnClick.TOPIC1 data : hello world, TOPIC1
}
pubsub-js
をimportしておけば、別ファイルや別クラスの内部でもカスタムイベントを発行・購読できる。インスタンスを生成してtopic1.btnClick.TOPIC1
みたいにしなくてよいので、慣れれば便利。
参考
javascriptで発行/購読パターンを使ってモジュールの関係を疎結合に保つ
【JSでデザインパターン】オブザーバ編
結論
個人的にはEventEmitterとjQueryのtriggerが使いやすくて好き。
自作もできるけど、ややこしくなるのでやめたほうがいい
シンプルな EventDispatcher つくりました