フロントエンド開発プロセス中に、ページ要素にイベントを追加する問題に遭遇することがよくあります。また、ページ構造に直接追加されるなど、イベントを追加するための多くのJSメソッドや、いくつかのJSイベント監視方法も含まれています。各ブラウザにはイベントバブルイベントモニタリングのメカニズムが異なるため、LEブラウザにはイベントバブルのみがイベント監視メカニズムがなく、イベントリスニングの互換性の問題が最大の問題です。
1.ページ構造にイベントメソッドを直接書き込む
function eventfun(){//console.log(this); } <入力型= "button" onclick = "eventfun()" value = "button"/> //これにはこの範囲の問題が含まれます。 EventFunもここでグローバルな機能です。オブジェクトは[オブジェクトウィンドウ]であり、これはウィンドウを指します。このスコープの問題を解決するために、イベント変数をグローバル関数に追加する方法を使用し、このオブジェクトをページ構造内の関数のパラメーターとして渡すことができます
<入力型= "button" onclick = "eventfun2(this)" value = "button2"/> function eventfun2(eve){//ここで、イベントオブジェクトはグローバルメソッドEve.name = "alex"のパラメーターとして渡されます。 window.name = "robin"; console.log(this); // [object window] console.log(eve); // [object htmlinputelement] console.log(this.name); // robin console.log(eve.name); // alexvar self = eve; console.log(this.name); // robin console.log(self.name); // alex alert(window.name);アラート(self.name); }2。イベント属性に値を割り当てる方法を使用することは、イベントへの拘束方法ですが、この方法の制限は、イベントに1つの方法しかバインドできないことです。複数のバインディングがバインドされている場合、1つの方法が勝ちます。
htmLelementObject.onclick = fucntion(){//このメソッドを使用してイベント属性に値を割り当てると、このポインターはイベントオブジェクトではなくウィンドウオブジェクトを指します。
// js code fun1(); fun2(); fun3(); console.log(this); // window.object} function dosomething(){// js code} htmlelementobject.onclick = dosomething; //イベントオブジェクト属性にこの形式の割り当て値を使用すると、このポインターはイベント実行オブジェクトconsole.log(this);3。イベントの伝播 - バブルとキャプチャ
DOM Event Standardは、2つのイベントストリームを定義します。これらは大幅に異なり、アプリケーションに大きな影響を与える可能性があります。これらの2つのイベントストリームは、キャプチャとバブルです。多くのWebテクノロジーと同様に、NetscapeとMicrosoftは標準になる前にそれらを異なる方法で実装しました。 Netscapeはキャプチャイベントストリームを実装することを選択し、Microsoftはバブルイベントストリームを実装しました。幸いなことに、W3Cは両方の方法を組み合わせて使用することを決定し、ほとんどの新しいブラウザーはこれら2つのイベントストリーミング方法に従います。
デフォルトでは、イベントはバブルイベントストリームを使用し、キャプチャイベントストリームは使用されません。ただし、FirefoxとSafariでは、イベントを登録してこのパラメーターをTrueに設定するときに、UseCaptureパラメーターを渡すことにより、キャプチャイベントストリームの使用を明示的に指定できます。
バブルイベントストリーム
たとえば、イベントがDOM要素でトリガーされると、ユーザーはクライアント名ノードのマウスをクリックします。イベントは、イベントタイププロセッサに接続されているノードに遭遇するまで、ノードがDOMノード階層全体を介して泡立つさまざまな親ノードに従います。現時点では、イベントはOnClickイベントです。イベントの泡立ちは、泡立つプロセス中にいつでも終了できます。 W3C標準に準拠するブラウザでは、イベントオブジェクトのStopPropagation()メソッドを呼び出すことができ、Internet Explorerでは、イベントオブジェクトのcancelbubble属性をTrueに設定できます。イベントが停止しない場合、イベントはドキュメントルートに到達するまでDOMを通過します。
イベントフローをキャプチャします
イベントの処理は、イベントをトリガーするターゲット要素からではなく、DOMレベルのルートで始まり、イベントはターゲット要素のすべての祖先要素から順番に渡されます。このプロセスでは、イベントは、ドキュメントルートからイベントターゲット要素までのさまざまな継承された派生要素によってキャプチャされます。イベントリスナーが登録時にusecapture属性をtrueに設定する場合、この期間中に任意の要素に割り当ててイベントを処理できます。それ以外の場合、イベントは、ターゲット要素まで導出された要素パスの次の要素に渡されます。イベントがターゲット要素に到達すると、Domノードを介して泡立ちます。
最新のイベントバインディング方法
以前のレッスンでは、従来のイベントバインディングを使用すると、オブジェクトの同じイベントに複数のイベントハンドラーを登録できないなど、多くの欠点があります。また、ブラウザとW3Cはこれを考慮していないわけではないため、最新のブラウザでは、イベントをバインドする独自の方法があります。
W3C DOM
obj.addeventlistener(evtype、fn、usecapture)-w3cは、イベント処理機能を追加する方法を提供します。 objはイベントを追加するオブジェクトであり、evtypeはイベントタイプであり、プレフィックスがありません。fnはイベントハンドラー関数です。ユーザーキャプチャが真である場合、イベントハンドラー関数はキャプチャステージで実行されます。
obj.removeeventlistener(evtype、fn、usecapture)-w3cは、イベント処理機能を削除する方法を提供します
Microsoft IEメソッド
obj.attachevent(evtype、fn) - イベント処理機能を追加するためにIEによって提供される方法。 objはイベントを追加するオブジェクトであり、evtypeはイベントタイプであり、プレフィックスの上に、fnはイベントハンドラー関数、つまりイベントキャプチャをサポートしていません
obj.detachevent(evtype、fn、)-IEは、イベント処理機能を削除する方法を提供します。EVTypeはプレフィックスに含まれます
両方を統合する方法
関数addEvent(obj、evtype、fn、usecapture){if(obj.addeventlistener){obj.addeventlistener(evtype、fn、usecapture); } else {obj.attachevent( "on"+evtype、fn); // ieはイベントキャプチャをサポートしていません} else {obj ["on"+evtype] = fn; // obj.removeeventlistener(evtype、fn、usecapture); } else {obj.detachevent( "on"+evtype、fn); } else {obj ["on"+evtype] = null; }}IE Attachメソッドには問題があります。つまり、ActibleEventを使用する場合、これはOBJではなくウィンドウを指します!もちろん、これには解決策があります!
しかし、IEのAttachmentEventメソッドには別の問題があります。同じ関数を同じオブジェクトと同じイベントに複数回登録できます。解決策:IEのAttachmentEventメソッドを放棄します! IEに基づくAttachEventメソッドは、従来のイベント登録(複数のイベントハンドラーをバインドすることを除く)とそれほど変わらないキャプチャをサポートしておらず、IEのAttachmentEventメソッドにはメモリリークの問題があります。
AddEvent、Delevent Modernバージョン
<!doctype html public " - // w3c // dtd xhtml 1.0 transitional // en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <meta http-equiv = "content-type" content = "text/html; charset = utf-8"/> <title> js event </title> <stly> <stly:12pcx;ボーダーボトム:1px solid #efefefef;} < /style> < /head> <body> <div id = "outele" style = "padding:" padding:10px; border:1px solid#b2b2b2; background:#efefefef onclick = "eventfun2(this);" id = "button2" value = "button2" /> <br /> <input type = "button" button "button =" button3 "button3" /> <br /> <input type = "button" button4 "value =" button4 " /> <table id =" htmleletable "style =" border:1px solid#b2b2; id="1111"><td>111111111111111111111111111111</td></tr> <tr id="22222"><td>222222222222222222222222222222</td></tr> <tr ID = "33333333333333333333333333333333333333 </td> </tr> <tr id="44444"><td>44444444444444444444444444444444444444444444444444444444444444444444444444444444444444 44444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444</td></tr> <TR ID = "55555555555555555555555555555555 </td> </tr> </table> </div> <スクリプト言語=" javascript "type =" text/javascript "> function eventfun(){// 1。 JSメソッドをPage Structure Console.log(this); //これには、この範囲に問題が含まれます。 EventFunはグローバル関数であり、オブジェクトはウィンドウであり、これはウィンドウアラート(This)を指します。 } function eventfun2(eve){//ここで、イベントオブジェクトをグローバルメソッドにパラメーターとして渡すeve.name = "alex"; // window.name = "robin"; console.log(this); // [object window] console.log(eve); // [object htmlinputelement] console.log(this.name); // robin console.log(eve.name); // alex var self = eve; console.log(this.name); // robin console.log(self.name); // alex alert(window.name);アラート(self.name); }関数eventFun3(){// 1。 Page Structure Console.log(this); //これには、この範囲の問題が含まれます。 eventFunはグローバル関数であり、オブジェクトはウィンドウであり、これはウィンドウコンソール.log(this.id)を指します。アラート(これ);アラート(これ);アラート(this.id); // var outeleobj = eventutil。$( "outele"); // removeEvent(outeleobj、 "click"、eventfun3); } /* var eventutil = {}; eventutil。$ = function(id){return document.getElementById(id); } eventutil.openmes = eventfun3; eventutil.addeventhandle = function(eventTarget、eventType、eventHandle){//オブジェクト要素、イベントリスニングのイベントタイプ、イベント機能(eventTarget.attachevent){eventTarget.attachevent( "on"+eventType、eventhandle); } else if(eventTarget.addeventListener){eventTarget.addeventListener(eventType、eventHandle、false)} else {eventTarget ["on" + eventType] = null; }}; eventutil.deleeventhandle = function(eventTarget、eventType、eventHandle){//オブジェクト要素、イベントリスニングのイベントタイプ、イベント機能(eventTarget.Detachevent){alert( "on"+eventType); alert( "on"+eventhandle); eventTarget.detachevent( "on"+eventType、eventHandle); } else if(eventTarget.RemoveEventListener){eventTarget.RemoveEventListener(eventType、eventHandle、false)} else {eventTarget ["on" + eventType] = null; }};*/ var eventutil = {$:function(id){return document.getElementById(id); }、but4fun:function(){console.log(this); this.addeventhandle(); }、eventfun3:function(){console.log(this);アラート(これ); Delevent(obj、evtype、fn、usecapture); }} /*** addeventListenerを使用して、リスニング機能addevent(obj、evtype、fn、usecapture){if(obj.addeventlistener){obj.addeventlistener(evtype、fn、usecapture); } else if(obj.attachevent){obj.attachevent( "on"+evtype、function(){fn.call(obj);}); } else {obj ["on"+evtype] = fn; //実際、この状況は存在しません}} function delevent(obj、evtype、fn、usecapture){if(obj.removeeventlistener){obj.removeventlistener(evtype、fn、usecapture); } else if(obj.detachevent){obj.detachevent( "on"+evtype、fn); } else {obj ["on"+evtype] = null; }} function addevent(obj、evtype、fn、usecapture){if(obj.addeventlistener){// W3Cイベント登録スキームobj.addeventlistener(evtype、fn、!! usecapture)の優先度が与えられます。 } else {// addeventlistenerがサポートされていない場合(つまり)、IEは同時にキャプチャをサポートしていないため、従来のイベントバインディングを使用する方が良い場合は(!fn .__ eventId){fn .__ eventid = addevent .__ eventhandlescounter ++;} // _ EventHandles属性は、すべてのイベントハンドラーへの参照を保存するために使用されますif(obj ["on"+evtype])){//イベント処理関数は以前に従来の方法で登録されていました(obj .__ eventhandles [evtype] [0] = obj ["on"+evtype]).__ eventid = 0; obj ["on"+evtype] = addevent.execeventhandles; //イベントが発生したとき、execeventhandlesはテーブルを横断しますobj .__ eventhandles [evtype]を実行し、その中の関数を実行}}}}} addevent .__ eventhandlescounter = 1; // counter、addevent.exeventhandles = function(evt){// returity bit retranquility unt execute if if( true;} evt = evt || window.event; var fns = this .__ eventhandles [evt.type]; for(fns in fns){fns [i] .call(this); }}; /* function delevent(obj、evtype、fn、usecapture){if(obj.removeeventlistener){//最初にw3cメソッドを使用してイベントハンドラー機能obj.removeeventlistener(evtype、fn、!! usecapture); } else {if(obj .__ eventhandles){var fns = obj .__ eventhandles [evtype]; if(fns){delete fns [fn .__ eventid];}}}}} function fixevent(evt){// fixevent関数は個別に実行されません。イベントオブジェクトパラメーターが必要であり、イベントが発生したときにのみ実行されます!最良の方法は、それをAddEvent関数のexeceventhandlesに統合することです。(!evt.target){evt.target = evt.srcelement; evt.preventdefault = fixevent.preventdefault; evt.stoppropagation = fixevent.stoppropagation; if(evt.type == "mouseover"){evt.relatedTarget = evt.fromelement; } else if(evt.type == "mouseout"){evt.relatedTarget = evt.toelement; } evt.CharCode =(evt.Type == "keypress")?evt.keycode:0; evt.eventphase = 2; // ieはバブルステージでのみ動作しますevt.timestamp =(new date())。 } fixevent.preventdefault = function(){this.returnvalue = false; //これは、fixeventではなく特定のイベントオブジェクトを指します}; fixevent.stoppropagation = function(){this.cancelbubble = true; };*////Console.log(Eventutil.$("button3"));//Return eventutil functionのオブジェクト属性//eventutil.$("button3").onclick= eventfun; // 2。値をオブジェクトイベント属性に割り当てる方法を使用して、イベントのリスニング//eventutil.$("button3").onclick= eventfun2; //イベント属性に複数のメソッドを追加する場合、後者は//eventton3").onclick= eventfun; = function(){function getByid(id){return document.getElementById(id); }; // Dean Edwards、2005によって書かれた// Tino Zijdel、Matthias Miller、Diego periniからの入力} else {//各イベントハンドラーを割り当ててください。 //要素のイベントタイプのハッシュテーブルを作成するif(!element.events)element.events = {}; //各要素のイベントハンドラーのハッシュテーブルを作成します/イベントペアvarハンドラー= emevents [type]; if(!handlers){handlers = element.events [type] = {}; //既存のイベントハンドラーを保存します(1つがある場合)if(element ["on" + type]){handlers [0] = element ["on" + type]; }} //イベントハンドラーをハッシュテーブルハンドラーに保存[ハンドラー。$$ guid] =ハンドラー; //すべての作業要素を実行するためにグローバルイベントハンドラーを割り当てます["on" + type] = handleEvent; }}; //一意のIDを作成するために使用されるカウンターaddevent.guid = 1;関数removeEvent(element、type、handler){if(element.removeeventlistener){element.removeeventlistener(type、handler、false); } else {//ハッシュテーブルからイベントハンドラーを削除するif(element.events && element.events [type]){delete element.events [type] [handler。$$ guid]; }}}; function handleevent(event){var returnValue = true; //イベントオブジェクトをつかむ(つまり、グローバルイベントオブジェクトを使用する)イベント=イベント|| fixevent(((this.OwnerDocument || this.Document || this).ParentWindow || Window).Event); //イベントハンドラーのハッシュテーブルへの参照を取得しますvarハンドラー= this.events [event.type]; //各イベントハンドラーを(ハンドラーのvar i){this。$$ handleevent = handlers [i]; if(this。$$ handerevent(event)=== false){returnValue = false; }} return returnValue; }; function fixevent(event){// w3c標準イベントメソッドを追加しますevent.preventdefault = fixevent.preventdefault; event.stoppropagation = fixevent.stoppropagation;戻りイベント。 }; fixevent.preventdefault = function(){this.returnValue = false; }; fixevent.stoppropagation = function(){this.cancelbubble = true; }; function tableaddevent(){}; return {add:addevent、remove:removeevent、$:getbyid}}(); var outeleobj = eventutil。$( "outele"); //addevent.apply(eventutil,, eventeleobj、 "click"、eventfun3]); //eventutil.add(outeleobj,"click"、eventfun3); var inputobj = eventutil。$( "button4"); var tableele = eventutil。$( "htmleletable"); var tabtrele = tableele.getelementsbytagname( "tr"); eventutil.add(tableele、 "click"、eventfun3); for(i = 0; i <tabtrele.length; i ++){eventutil.add(tabtrele [i]、 "click"、eventfun3); } eventutil.remove(tableele、 "click"、eventfun3); // event削除方法eventutil.add(tableele、 "click"、eventfun3); // eventutil.add(inputobj、 "click"、eventfun3); //eventutil.remove(outeleobj,"click"、eventfun3); //console.log(addevent); // addevent(inputobj、 "click"、eventfun3、true); // delevent(outeleobj、 "click"、eventfun3、false); </script> </body> </html>PS:ここでは、JSイベントに関するオンラインツールを提供します。これは、一般的に使用されるイベントタイプとJSの関数関数を要約しています。
JavaScriptイベントと機能の完全なリスト:
http://tools.vevb.com/table/javascript_event