在JavaScript中,常常會碰到要監聽清單中多項li的情形,假設我們有一個清單如下:
如果我們要實現以下功能:當滑鼠點擊某一li時,alert輸出該li的內容,我們通常的寫法是這樣的:
當列表項目比較少時,直接給每個li添加onclick事件
列表項比較多時,在onload時就給每個列表項呼叫監聽
第一種方法比較簡單直接,但沒有顧及到html與JavaScript的分離,不建議使用,第二種方法的程式碼如下:
由上可以看出來,假如不停的刪除或添加li,則function()也要不停的更改操作,易出錯,因此推薦使用事件代理,在使用事件代理之前,我們先來了解一下事件階段(event phase):
事件階段:
當一個DOM事件被觸發的時候,他並不是只在它的起源對像上觸發一次,而是會經歷三個不同的階段。簡而言之:事件一開始從文檔的根節點流向目標物件(捕獲階段),然後在目標對向上被觸發(目標階段),之後再回溯到文檔的根節點(冒泡階段)如圖所示(圖片來自W3C):
事件擷取階段(Capture Phase)
事件的第一個階段是捕獲階段。事件從文件的根節點出發,隨著DOM樹的結構往事件的目標節點流去。途中經過各個層次的DOM節點,並在各節點上觸發捕獲事件,直到到達時間的目標節點。捕獲階段的主要任務是履歷傳播路徑,在冒泡階段,時間會透過這個路徑回溯到文檔根節點。
我們透過上面的這個函數來給節點設定監聽,可以透過將;設為true來為事件的捕獲階段添加監聽回調函數。在實際應用中,我們並沒有太多使用捕獲階段監聽的用例,但是透過在捕獲階段對事件的處理,我們可以阻止類似click事件在某個特定元素上被觸發。
この使用法についてあまり詳しくない場合は、これを false または未定義に設定して、バブリング段階でイベントを監視することをお勧めします。
ターゲットフェーズ
イベントがターゲットノードに到達すると、イベントはターゲットステージに入ります。イベントはターゲット ノードでトリガーされ、最も外側のドキュメント ノードに伝播されるまで逆方向に流れます。
複数レベルのネストされたノードの場合、マウス イベントとポインター イベントは最も内側の要素に配置されることがよくあります。 div 要素にクリックリッスン関数を設定し、ユーザーが div 要素内の p 要素をクリックしたとします。このとき、p 要素がターゲット要素になります。イベント バブリングを使用すると、この div または上位レベルの要素でクリック イベントをリッスンし、時間の伝播中にコールバック関数をトリガーできます。
バブルフェーズ
ターゲット イベントでイベントがトリガーされた後、この要素では終了しません。最も外側のルート ノードに到達するまで、DOM ツリーに沿ってレイヤーごとにバブルしていきます。つまり、同じイベントが、ターゲット ノードの親ノード、親ノードの親ノード...最外側のノードまでで 1 回トリガーされます。
ほとんどのイベントはバブルしますが、すべてではありません。詳細については、仕様
を参照してください。上記のことから、イベント プロキシを使用して各 li を監視できると考えられます。コードは次のとおりです:
上記がこの記事の全内容です。JavaScript イベントの委任とプロキシについて皆さんが理解するのに役立つことを願っています。
この記事を友達と共有したり、コメントを残してください。皆様のご支援に心より感謝申し上げます。