はじめに
プラグインはこちら
利用例もsample/index.htmlにあるのでよろしければ
作成したきっかけ
最近jQuery無しで実装することもそれなりにあり、addEventlistener/removeEventlistenerを毎回書くのもしんどいなと思っていました。
そんな中とある実装で無名関数のremoveEventlistenerを実装しようとしたところ少し詰まりました。jQueryなら.off()を使っているところですね。
色々と調べていたところ、stackoverflowのこの課題にたどり着きました。
javascript - How to removeEventListener that is addEventListener with anonymous function? - Stack Overflow
中身を見るとクロージャーを使って無名関数や諸々の設定を保存しておくことによって解決を図っているようです。
しかし、こんなよく使いそうな関数をクロージャーによる管理でいいのかな?と思い至り、面倒に思っていたことも相まって、無名関数も容易に扱えてeventlistenerの記述も簡単にかけるものを作ってみようと思い今回のミニプラグインを作成しました。
実装方法や使い方など
stackoverflowの回答にあった方法論は理解できたので、これを参考にしつつ保存しておく関数やイベントタイプはコンストラクタに持たせ、event登録処理などはprototypeに登録することで作成しました。
ただ、このままでは元を少し書き直したくらいで自分で作る意味もないのでqueryselectorAllの対応、add/removeの別オプション対応、イベントの状態情報提供などを追加した上で最適化しjQueryライクに書けるよう作成しました。
核となる部分は以下のような感じです、まぁごくごく普通のクラス作成で特に小難しいテクニックなどはありません。
var EventSwitch = function(target, type, listener, option){
this.listener = listener;
this.target = target;
this.type = type;
this.option = option || false;
this.isActive = true;
this.switch('on');
}
EventSwitch.prototype.switch = function(order){
var _this = this;
var option = _this.option;
var listenerType = order === 'on' ? 'addEventListener' : 'removeEventListener' ;
_this.isActive = order === 'on' ? true : false ;
if(_this.option.isArray){
option = order === 'on' ? _this.option[0] : _this.option[1] ;
}
if(typeof _this.target === 'string'){
Array.prototype.slice.call(document.querySelectorAll(_this.target)).forEach(function(element){
element[listenerType](_this.type, _this.listener, option);
});
}else{
_this.target[listenerType](_this.type, _this.listener, option);
}
}
実際の使い方は以下のような形で一応目標にしていた簡易的な管理は出来るようになったかなと思います。
//登録
var clickEvent = esw('.trigger','click',function(event){ console.log(event); });
//削除
clickEvent.switch('off')
//再登録、アタッチ
clickEvent.switch('on')
//イベントが機能しているかどうか(boolean)
clickEvent.isActive
おわりに
最近OSSに興味があり、あまり大層なものは書けないですが普段つまづく事が多い内容はこまめにアウトプットして作れていけたらなと思います。
もしイベント管理面倒だなと思ったらぜひ使ってみてください。