私は、FileReaderがまるでDOM要素であるかのようにイベントをディスパッチすることを知りました。それは...ですか? HTML/XML構造の表現を持たないFileReaderに似たオブジェクトを作成することは可能ですが、イベントをディスパッチできますか?イベントは通常のオブジェクト(DOMオブジェクトではない)にディスパッチできますか?
答えて
FileReader
はaddEventHandler
のようなメソッドを持っています。 EventTarget
はDOM Events仕様で定義されていますが、実装するにはDOMオブジェクトである必要はありません。 window
,XMLHttpRequest
およびFileReader
は、EventTarget
を実装する他のブラウザオブジェクトモデルオブジェクトです。
残念ながら、ブラウザのイベントターゲットのネイティブ実装にピギーバックする簡単な方法はありません...ブラウザオブジェクトからprototype
プロパティを使用して継承することができますが、一般的には非常に信頼性がありません。しかしプレーンJavaScriptですべてのメソッドを自分で実装するコードを書くには余りにも難しいことではありません。
function CustomEventTarget() { this._init(); }
CustomEventTarget.prototype._init= function() {
this._registrations= {};
};
CustomEventTarget.prototype._getListeners= function(type, useCapture) {
var captype= (useCapture? '1' : '0')+type;
if (!(captype in this._registrations))
this._registrations[captype]= [];
return this._registrations[captype];
};
CustomEventTarget.prototype.addEventListener= function(type, listener, useCapture) {
var listeners= this._getListeners(type, useCapture);
var ix= listeners.indexOf(listener);
if (ix===-1)
listeners.push(listener);
};
CustomEventTarget.prototype.removeEventListener= function(type, listener, useCapture) {
var listeners= this._getListeners(type, useCapture);
var ix= listeners.indexOf(listener);
if (ix!==-1)
listeners.splice(ix, 1);
};
CustomEventTarget.prototype.dispatchEvent= function(evt) {
var listeners= this._getListeners(evt.type, false).slice();
for (var i= 0; i<listeners.length; i++)
listeners[i].call(this, evt);
return !evt.defaultPrevented;
};
注意:上記のコードの私の頭の上から未検証ですが、動作する可能性があります。しかし、Event
オブジェクトがDOMレベル3 defaultPrevented
プロパティをサポートし、DOMレベル3のサポートがない場合はdispatchEvent
戻り値をサポートするような制限があります。stopImmediatePropagation()
(実装不可能な独自のEventオブジェクトに依存しない限りそれ)。また、階層やキャプチャ/バブリングの実装もありません。
だからIMO:あなたはDOMイベントモデルに参加するコードを書いてみることはあまりありません。プレーンJSコールバックの仕事のために、リスナーリストの独自の特別な実装を行っています。
私はそれがjavascriptだと仮定します。通常、DOM要素への参照を取得できるオブジェクトはすべて、element.dispatchEvent関数を使用してイベントを送出できます。参照:それはEventTarget
インタフェースを実装するdefinedあるので
はい、これらのページから来ました。つまり、FileReaderはDOM要素に関連していないか、または参照があるようです。しかしそれと同時に、dispatchEventメソッド自体があり、イベント(私が推測するDOMイベント)をディスパッチできます。混乱は少しありますか?私は、同様のプロパティを持つオブジェクトを作成する方法があるのだろうかと思った。 – jayarjo
私はFileReaderを実装していませんので、推測だけですが、DOM要素が内部的にプライベートメソッドとして保持されていて、FileReaderのdispatchEventが内部のdispatchEventへの呼び出しを転送していたDOM要素、どうやって知っていますか? – phtrivier
内部DOM要素はどういう意味ですか?このような現実世界の言葉はありますか、それともあなたは再び推測していますか? :)内部DOM要素があれば、FileReaderは何も転送する必要がないと思います。それ自体が一つかもしれない。 – jayarjo
bobince has the right ideaですが、彼のコードは単なる例です。実際のバトルテスト実装の場合は、Mr. Doob has one that he uses in three.jsです。
ECMAScript APIのエミュレーションに関心がない場合は、[signals](http://millermedeiros.github.com/js-signals/)と[bacon](https://github.com/raimohanska/)も検討してください。 bacon.js)。 – bsimpson
jQueryは、通常のオブジェクトからイベントをディスパッチできます。 Here's a fiddle。
function MyClass() {
$(this).on("MyEvent", function(event) {
console.log(event);
});
$(this).trigger("MyEvent");
}
var instance = new MyClass();
私は自分自身のイベントモデルを持っています。ハンドラを「イベントタイプ」にバインドし、ハッシュに格納し、このモデルを継承するオブジェクト(および他のユーティリティメソッド)を「トリガする」関数を呼び出します。デフォルトのイベントモデルは私のものよりも貴重な利点はないとお考えですか? – jayarjo
ええ、利点は非常に小さいと思いますが、 'preventDefault' /' stopPropagation'/'stopImmediatePropagation'が確実に読み取れないため、' Event'の他の実装と実際に100%相互運用することはできません呼び出されました。だから、唯一の利点は、DOMイベントインターフェイスの親しみです...しかし、それは間違いなくかなりclunkyインターフェイスです。 – bobince
私はこれを見つけました:http://www.w3.org/TR/DOM-Level-3-Events/#interface-CustomEvent、ここでW3Cはアプリケーション固有のイベントタイプを作成することを推奨しています。限り、私はまだ広くはサポートされていない参照してください、しかし、それはすべてのものが向いているようです。 – jayarjo