2016-05-26 4 views
2

イベントのEventTargetの設定方法。イベントのイベントターゲットの設定方法

var myObj = {foo: 'bar'}; 
var event = new Event('eventName'); 
event.target = myObj; 

は、次のエラーになります:

Uncaught TypeError: Cannot set property target of #<Event> which has only a getter 

編集:

が、私は私のクラスはtargetになりますこのような何かを、書きたい:

class MyClass { 

    constructor() { 
    this.listeners = {}; 
    } 

    addEventListener(type, callback) { 
    if (!(type in this.listeners)) { 
     this.listeners[type] = []; 
    } 
    this.listeners[type].push(callback); 
    } 

    removeEventListener() { 
    if (!(type in this.listeners)) { 
     return; 
    } 
    var stack = this.listeners[type]; 
    for (var i = 0, l = stack.length; i < l; i++) { 
     if (stack[i] === callback) { 
     stack.splice(i, 1); 
     return this.removeEventListener(type, callback); 
     } 
    } 
    } 

    dispatchEvent(event) { 
    if (!(event.type in this.listeners)) { 
     return; 
    } 
    var stack = this.listeners[event.type]; 
    event.target = this; 
    for (var i = 0, l = stack.length; i < l; i++) { 
     stack[i].call(this, event); 
    } 
    } 

} 

let myInstance = new MyClass(); 
let event = new Event('eventName'); 
myInstance.dispatchEvent(); 

詳細情報:https://developer.mozilla.org/en/docs/Web/API/EventTarget

+1

私は誤解を招くかもしれませんが、通常は、イベントの発生/トリガーに使用された要素としてブラウザによって自動的に 'EventTarget'が設定されます。あなたは何をしようとしていますか?あなたの質問の限られた情報から、あなたが 'EventTarget.addEventListener()'を使っているべきだと感じていますが、私は今のところあなたの意図を非常によく確信しています。 –

答えて

2

あなたの編集に関して、それはと著しく表示されます。は質問を変更します。答えはCustomEventを使用しないでください。目的以外の目的で使用しようとしています。イベントをDOM要素にディスパッチしないので、独自のオブジェクトを使用してください。

targetElement.dispatchEvent(event); 

あなたは、単にプロパティとして追加し、イベントに要素以外のカスタムデータを含める場合:

あなたは イベントを送出したときにそれが自動的に設定されています


event.data = myObj; 

例:

"use strict"; 
 
var div = document.getElementById("target"); 
 

 
div.addEventListener(
 
    "eventName", 
 
    function(e) { 
 
    console.log("e.target:", e.target); 
 
    console.log("e.data:", e.data); 
 
    }, 
 
    false 
 
); 
 

 
var myObj = {foo: "bar"}; 
 
var event = new Event("eventName"); 
 
event.data = myObj; 
 
div.dispatchEvent(event);
<div id="target"></div>

+0

DOMElementをEventTargetにしたくありません。代わりに、私の選択のオブジェクトでなければなりません。 – HaNdTriX

+0

@HaNdTriX:あなたの編集は質問を非常に大きく変更します。 (基本的に答えが出てから質問が変わるのは許されません。私はこれがほんのわずかです。)新しい質問に答える答えを編集しました。 –

+0

私はDOM要素について一度も言及していません。私は問題を本質的な部分に減らそうとしました。 Javascriptでは、イベントにDOM要素ではないターゲットがある多くの例があります。 (例:通知イベント)これについて不明な点がございましたら、 – HaNdTriX

1

それはあなたの元の質問から9ヶ月で、1年だと私は正確に同じ場所から、まったく同じコードで正確にこれを行うにしたいです。私はあなたがこれをやりたい理由を正確に知っています。なぜなら、EventTargetはまだすべてのブラウザで構成可能なオブジェクトではないからです。そして、それはあなたの問題に対する本当の解決策はないと思われます。

他の誰かがこの問題を抱えていて、このページを突き抜けた場合、解決策はEvent.targetに依存しないことです。あなたはカスタムイベントを作成し、このようにそれを派遣することができます。

var myeventtarget = new MyClass(); 

var ev = new CustomEvent('myevent', { 
    detail: { 
     target: myeventtarget 
    }}); 

myeventtarget.dispatchEvent(ev); 

その後、イベントハンドラで、ターゲットを使ってアクセスすることができます。

var event_handler = function(ev) { 
    var target = ev.detail.target; 
    alert(target); 
} 

それは本当に醜い構文だが、それは次のようになりますこれは今すぐ達成できる「適切な」方法だけです。あなたは古いブラウザを無視するならば今、私は新しいFirefoxとChromeのブラウザで、あなたはこのようMyClassを実装することができることを知っている:私がテストしていない

class MyClass extends EventTarget { 
    constructor() { 
     super() 
    } 
} 

のオブジェクトにディスパッチされたときにイベントターゲットが設定されているかどうか上記の定義を入力してMyClassと入力してください。そうでない場合は、明らかに理にかなっているため、DOM Living Standardの変更として提案する価値があります。(現在の仕様では動作するはずはありません)

最後に、使用しているjavascript EventTargetコードを最初に正しくチェックせずに注意してください。私はあなたがそれを渡すときにそれが壊れていることを発見したEventListenerオブジェクト。同じイベントをaddEventListener()に2回渡すと、重複イベントが追加されますが、DOMリビングスタンダードではそうしてはならないと明確に述べられています。幸いにもこれらの問題を解決するのは非常に簡単です。

if (stack[i].handleEvent) stack[i].handleEvent(event); 
     else stack[i].call(this, event); 

し、以下を追加します:あなたはにstack[i].call(this, event);を変更する必要が

var stack = this.listeners[type]; 
for (var i = 0, l = stack.length; i < l; i++) { 
    if (stack[i] === callback){ 
     return; 
    } 
} 

this.listeners[type].push(callback);前に他の問題(あなたがそれをヌルコールバックを渡した場合 addEventListener()は単純に戻らないということですもう一つの簡単な修正)、明らかにオプションを渡すことはできません。 (しかし、あなたが本当にこの機能を必要としているかどうかを判断してください)

0

私はちょうど脳波がありましたので、あなたには別の答えがあります。それは非常にいたずらです。はちょうどを働かせるかもしれません。 (私のために働いた;)代わりにevent.target = myObjを行うの

、あなたが試みることができる:

Object.defineProperty(event, 'target', {writable: false, value: myObj}); 

を私はここで間違っているかもしれないが、私は何が起こることは、新たなtargetプロパティは、元の1を隠していることだと思います。これは、ブラウザの内部イベントのディスパッチと同じ方法では動作しません。ブラウザイベント処理コードではほとんど無視されますが、Event.targetに依存するJavaScriptコードを欺くだけで十分でしょう。

また、一部のブラウザでは、構成不可能なプロパティとしてEvent.targetが定義されている可能性があるため、異なるブラウザでテストするように注意してください。

関連する問題