2016-05-09 9 views
0

最近のプロジェクトで私はいくつかのコードを継承してくれました。addEventListenerがインラインで追加された理由は、参照された関数immediatlyのonclick fireですか?

インラインonclick関数からイベントリスナーを追加すると、すぐにaddEventListner()で参照されている関数が呼び出される理由は誰でも説明できますか?

function refFunction() { 
 
    console.log("Test Function"); 
 

 
    if (document.removeEventListener) { 
 
    document.removeEventListener('click', refFunction, false); 
 
    } else if (document.detachEvent) { 
 
    document.detachEvent('onclick', refFunction); 
 
    } 
 
} 
 

 
function addEvtLstnr() { 
 
    if (document.addEventListener) { 
 
    document.addEventListener('click', refFunction, false); 
 
    } else if (document.attachEvent) { 
 
    document.attachEvent('onclick', refFunction); 
 
    } 
 
}
<input type="button" value="Add Evt listener" onClick="addEvtLstnr();">

ここJSfiddleを参照してください:私は希望Example JSFiddle

効果は、ボタンのonclickのインラインでイベントハンドラを追加することですが、それに対して発生しません参照された関数を呼び出す。

任意の助けを理解され、

J.
+0

@RobGこれは論争の的になるアドバイスです:なぜそれが開発者が望んでいないものであれば、イベントを伝播するのはなぜですか。 – zerkms

+0

@ zerkms-oops、回答を回答に変更しました。タイムアウトを使用すると問題が回避されます。代わりに、イベントの伝播を停止することもできますが、応答する他のリスナーが存在する可能性があります。実際にどちらがより良いアプローチであるかを判断するためには、営業担当者に任されています。私は私の答えを更新します。 – RobG

+0

あなたのコードを読んで、言葉で説明したあなたの要件を読むことは、矛盾していて相反するものです。 コードを読むと、入力ボタンを使用してイベントを1回だけ発生するドキュメント要素に割り当てることが目的であることがわかります。すなわち、それが発射された直後に除去される。次のように:https://jsfiddle.net/ajkhtf7q/3/ –

答えて

3

ボタンがクリックされたときに聴取者が文書に追加されます。次に、クリックイベントがドキュメントにバブルして、リスナを起動します。

これを避けるには、イベントが追加される前にバブリングが完了するように、タイムアウトを使用してリスナーを追加します。

また、イベントの伝播を停止してバブルしないようにすることもできます。

function refFunction() { 
 
    console.log("Test Function"); 
 

 
    if (document.removeEventListener) { 
 
    document.removeEventListener('click', refFunction, false); 
 
    } else if (document.detachEvent) { 
 
    document.detachEvent('onclick', refFunction); 
 
    } 
 
} 
 

 
function addEvtLstnr() { 
 
    if (document.addEventListener) { 
 
    document.addEventListener('click', refFunction, false); 
 
    } else if (document.attachEvent) { 
 
    document.attachEvent('onclick', refFunction); 
 
    } 
 
}
// Call addEvtLstnr after a pause so event finishes bubbling before listener added 
 
<input type="button" value="Add Evt listener" onclick="setTimeout(addEvtLstnr, 0);"> 
 

 
// Stop propagation of the event so that it doesn't reach the listener 
 
<input type="button" value="Add Evt listener 2" onclick="addEvtLstnr();event.stopPropagation();">

ところで、関数の宣言はセミコロンで終了していません。 ;-)

0

引用:「インラインonclick関数からイベントリスナーを追加すると、すぐにaddEventListner()で参照されている関数が呼び出されるのはなぜですか?まさに真実ではない

は、イベントが最後に、あなたが実際にイベントリスナーを追加した時ルート要素に達し、火災できるようにするために、かなりの数の要素をを伝播する必要があります。

ルート要素は、クリックイベントリスナーが割り当てられた後、入力要素でクリックイベントを受け取ります。したがって、規定通りに起動する必要があります。

関連する問題