JavaScript事件は泡が発生して、事件は逮捕して、事件は処理して、事件は委託します.


初期のイベントは、サーバーの負荷を分担する手段として、ドキュメントやブラウザのウィンドウで発生する特定のインタラクションの瞬間、ボタンをクリックしたり、ファイルをドラッグ&ドロップしたりします.イベントを予約するためにトランシーバーを使用することができ、イベントが発表されると、対応する応答を行うことができます.このモードは観察者モデルと呼ばれます.
事件の流れ
イベントストリームは、ページからイベントを受信する順序である.つのhtmlページの中で、dom元素は1粒のdom木を構成して、子の元素の普通のありかの位置がいずれも父の元素の中にあるためです.このサブ要素がクリックされると、サブ要素がクリックされたと考えられます.また、親要素がクリックされたと考えられます.このクリックイベントを誰が先に受け取るかを確認すると、ブラウザで解決すべき問題になります.
事件が勃発する
IEは、上述したイベントを処理する際に、イベント開始の最も具体的な要素(ドキュメント内のネストレベルの最も深いノード)によって受信され、その後、ステージごとにルートノードに伝播する.これは事件の泡が立つことです.



    
    test


    

在如上代码里面,如果单击了div元素,那么接着、、document会按着顺序收到点击事件。

事件捕获


Netscape Communicator团队提出了一种与IE完全相反的一种解决办法,接收事件的顺序为根节点到具体的节点,这种方法就是事件捕获。也就是在上面的这个例子中,接收点击事件的顺序为document、、、

DOM事件流


“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,然后处于目标阶段,最后才事件冒泡。依然以上面的代码为例子,单击div时,首先document获得点击事件,依次到、,之后事件捕获结束。事件捕获的意义在于,能够在目标获得点击事件之前截获事件,并对其作出相应的处理。处于目标阶段时,div能够执行绑定的事件处理程序,之后再到事件冒泡阶段。即使“DOM2级事件”规范明确规定捕获阶段不会涉及事件目标,但是浏览器基本都会 实现在捕获阶段触发事件对象上的事件,也就是说,可以在事件捕获阶段触发事件对象的事件处理程序,这种情况通常都需要在绑定事件处理程序的情况下指明可在捕获阶段触发。如果非必须,最好不要使用事件捕获。

事件处理程序


HTML事件处理程序


dom元素一般都有支持事件的特性,例如onclick等,这个特性的值应该是能够执行的JavaScript代码,这些JavaScript代码就是其事件处理程序,例如:

ページの他の場所で定義されたスクリプトを呼び出すこともできます.


    function handler() {
        alert('click');
    }
HTMLページで指定されたイベントハンドラには三つの欠点があります.時差があり、シナリオがイベントdom要素に結合されている場合、ユーザはシナリオがロードされていない過程でイベントがエラーを引き起こします.もう一つの欠点は、このようにイベントハンドラの役割領域チェーンを拡張することによって、異なるブラウザで異なる結果、すなわちthisの指向が一致しないということである.最後に、このような緊密な結合コードのスタイルはメンテナンスのコストが高くなり、コードを修正する時にHTMLコードとjsコードを修正する必要があります.
DOM 0レベルイベントハンドラ
JavaScriptでイベントハンドラを指定する従来の方法は、イベントハンドラの属性に関数を付与することです.このような指定されたイベントハンドラは、ブラウザをまたぐ簡単な利点があり、イベントハンドラはイベントフローの発泡段階でトリガされます.



    
    test


    
    
        var button = document.getElementById('myButton');
        function handler() {
            alert('click');
        }
        button.onclick = handler;
        //     
        // button.onclick = null;
    

このような方法は同じ要素で同じイベントに対して複数のイベントハンドラを指定することはできません.何度も結合すると、最後のイベントに準じます.
DOM 2レベルイベントハンドラ
DOM 2レベルイベントは、イベントハンドラの指定と削除を処理するための2つの方法を定義しています.これらは三つのパラメータを受け入れます.処理されたイベント名、イベントハンドラ、一つはイベントの泡立ちかそれともイベントのキャプチャ段階で処理されたブール値を指定します.trueはイベントキャプチャ段階で処理します.falseはイベントの泡立ち段階で処理します.注意したいのは、addEventListener()で指定されたイベントハンドラを通じて、removeveveventListener()でスマートに除去することです.一方、addEventListener()の2番目のパラメータが匿名関数であると、removeveveveveventListener()を通じて除去できなくなり、除去することもできません.一方、IEは、DOMと同様の2つの方法を実現した:atachEvent()とdetachEvent()、この2つの方法は直接に2つのパラメータを収め、最初はイベント名(注意イベント名は全部onプレフィックス、例えば、clickイベントはonclick)であり、第2のパラメータはイベントハンドラ関数である.以下の例は、ブラウザ対応イベントバインディング関数です.



    
    test


    
    
        function addHandler(element, type, handler) {
            if (element.addEventListener) {
                element.addEventListener(type, handler, false);
            } else if (element.attachEvent) {
                element.attachEvent('on' + type, handler);
            } else {
                element['on' + type] = handler;
            }
        }

        function removeHandler(element, type, handler) {
            if (element.removeEventListener) {
                element.removeEventListener(type, handler, false);
            } else if (element.detachEvent) {
                element.detachEvent('on' + type, handler);
            } else {
                element['on' + type] = null;
            }
        }

        var button = document.getElementById('myButton');

        function handler() {
            alert('click');
        }

        addHandler(button, 'click', handler);
        // removeEventListener(button, 'click', handler);
    

イベント依頼
実際には、ブラウザに割り当てられたオペレーティングシステムのリソースは他のデスクトップアプリケーションよりも少なくなります.主にハッカーがウェブページのアプリケーションを利用して大量の計算を行うことを恐れています.JavaScriptはウェブページの応用性能に影響を与えます.例えば、各関数は対象です.メモリを占用します.メモリのオブジェクトが多いほど、性能が悪いです.第二に、事前にすべてのイベントハンドラを指定しなければならないため、DOMアクセス数が多くなると、ページ間の相互作用の準備時間が長くなります.複数のイベントハンドラが多すぎると、イベントの性能が低下します.この問題を解決する方法は、イベント依頼です.イベント依頼は、イベントの泡を利用して、一つのイベントハンドラを指定するだけで、ある種類のすべてのイベントを管理することができます.例えば、DOMツリーにできるだけ高いレベルでイベントハンドラを追加してもよく、その後、イベントターゲット要素を操作しても良い.



    
    test


    
    
        function addHandler(element, type, handler) {
            if (element.addEventListener) {
                element.addEventListener(type, handler, false);
            } else if (element.attachEvent) {
                element.attachEvent('on' + type, handler);
            } else {
                element['on' + type] = handler;
            }
        }

        function removeHandler(element, type, handler) {
            if (element.removeEventListener) {
                element.removeEventListener(type, handler, false);
            } else if (element.detachEvent) {
                element.detachEvent('on' + type, handler);
            } else {
                element['on' + type] = null;
            }
        }

        var list = document.getElementById('myLinks');

        function handler(event) {
            event = event ? event : window.event;
            var target = event.target || event.srcElement;
            switch(target.id) {
                case 'doSomething':
                    alert('doSomething');
                    break;
                case 'goSomewhere':
                    alert('goSomewhere');
                    break;
                case 'sayHi':
                    alert('hi');
                    break;
            }
        }

        addHandler(list, 'click', handler);
        // removeEventListener(list, 'click', handler);
    

上記のコードから、一つのDOM要素だけを取得し、一つのイベントハンドラを追加したので、メモリの使用を減らすことができます.しかし、mouseoverおよびmouseoutは、マウスがある要素からそのサブノードに移動したとき、またはマウスがその要素を除去したときに、mouseoutイベントをトリガするため、イベントエージェントを使用することを推奨しない.