JavaScript中的事件

来源:http://www.cnblogs.com/sunwubin/archive/2016/10/06/5933717.html
-Advertisement-
Play Games

最近一段時間正在對JavaScript進行學習,知識太多,需要進行實際的使用和總結,國慶長假正好有時間,寫了下麵對JavaScript總結,可能對事件的理解還不夠完善,希望讀者多多指導,拍磚,我將不勝感激。好了直接如題吧。 JavaScript中的事件流 DOM2級事件規定事件流分為3個階段: 第一 ...


最近一段時間正在對JavaScript進行學習,知識太多,需要進行實際的使用和總結,國慶長假正好有時間,寫了下麵對JavaScript總結,可能對事件的理解還不夠完善,希望讀者多多指導,拍磚,我將不勝感激。好了直接如題吧。

JavaScript中的事件流

DOM2級事件規定事件流分為3個階段:

第一階段:事件捕獲階段,先由文檔的根節點Window->Document->html->body…往事件觸發對象,從外向內捕獲事件對象。

第二階段:目標階段,到達目標事件位置,觸發事件;

第三階段:事件冒泡,再從目標事件位置往文檔的根節點方向,反向冒泡。

事件捕獲和事件冒泡的先後順序如上圖顯示的步驟(1)、(2)、(3)。

在此簡單的做一下上面的捕獲和冒泡的實驗:

環境就以常用的Chrome瀏覽器,代碼如下:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title>Event</title>
 5 </head>
 6 <body>
 7     <div id="btn-big-test"> div1
 8         <br/>
 9         <br/>
10         <div id="btn-big-test2">div2</div>
11     </div>
12 </body>
13 <script type="text/javascript">
14 var el = document.getElementById('btn-big-test');
15 var el2 = document.getElementById('btn-big-test2');
16 el.addEventListener('click', function(event) {
17     console.log("冒泡1>>" + Date.parse(new Date()));
18 }, false);
19 
20 el.addEventListener('click', function() {
21     console.log("捕獲1>>" + Date.parse(new Date()));
22 }, true);
23 el2.addEventListener('click', function() {
24     console.log("冒泡2>>" + Date.parse(new Date()));
25 }, false);
26 
27 el2.addEventListener('click', function() {
28     console.log("捕獲2>>" + Date.parse(new Date()));
29 }, true);
View Code

運行結果如下如下:

 

 

看來結果卻不是我們想象的那樣 先執行捕獲在執行冒泡,那麼問題來了,是什麼問題。想了下不如把下麵兩個註冊事件換一下順序:

1 el2.addEventListener('click', function() {
2     console.log("捕獲2>>" + Date.parse(new Date()));
3 }, true);
4 
5 el2.addEventListener('click', function() {
6     console.log("冒泡2>>" + Date.parse(new Date()));
7 }, false);
View Code

運行結果如下:

現在好了,運行的結果和想象的一樣,那麼之前怎麼會不一樣的呢?順便把這幾個全部的順序都換一下,發現無論怎麼換 “捕獲1”都會先列印出來,但是事件觸發的元素的捕獲和冒泡的事件會因為順序不一樣而不同。

由此可見:事件流確實是先由外向內先捕獲,在向外冒泡,觸發的元素這不同,觸發元素是事件的目標元素,那麼它的捕獲和觸發呢,那就是根據事件註冊的先後順序不同來執行的。

說完了事件流的流程,再來說下事件的觸發吧。

事件是用戶或瀏覽器自身執行的某種動作。如click、load和mouseover,都是事件的名字,而響應某個事件執行的函數就是事件處理程式,那麼怎麼進行事件綁定了,其實上面已經有了,

(1)、執行 addEventListener(‘click’,function(){}, false),就表示註冊了一個click事件。

(2)、在html 標簽中使用 onclick=”yourfunction()” 這個是最常見的方式。

如果你發現addEventListener在ie裡面註冊不了事件,這是因為IE不同需要採用attachEvent ('onclick', function(){}) 來綁定事件

(3)事件移除則使用removeEventListener或detachEvent

在此我們已經知道瞭如何給元素綁定事件,那麼觸發事件對象中包含哪些內容呢?

 

事件類型

UI事件、焦點事件、滑鼠事件、滾輪事件、文本事件、鍵盤事件、合成事件、變動事件、變動名稱事件。暫時不做詳細總結,下次待完善

記憶體和性能

JS的世界里,每個函數都是對象,都會占用記憶體;記憶體中的對象越多,性能就越差。其次,必須事先指定所有事件處理程式而導致的DOM訪問次數,會延遲整個頁面的交互就緒時間。事實上,從如何利用好事件程式的角度出發,還是有一些方法能夠提升性能的。

“事件處理程式過多”問題的解決方案就是事件委托。事件委托利用了事件冒泡,只指定一個事件處理程式,就可以管理某一類型的所有事件。例如,click事件會一直冒泡到Document層次。也就是說我們可以為整個頁面指定一個onclick事件處理程式,不必每個元素添加處理事件。多個元素點擊的事件合併根據event.target.id來確定處理邏輯,這樣雖然代碼處理函數變長,但是消耗會更低。如果可行是否可以在document對象添加一個事件處理程式,用於處理頁面的某種特定類型的事件,

1)、Doucument對象很快就可以訪問,而且可以在頁面生命周期的任何時間點上為它添加程式(無須等待DOMContentLoaded或load事件)。也就是說,只要可點單擊的元素呈現在頁面上,就可以立即具備適當的功能。

2)、在頁面中設置事件處理程式所需的時間更少。只添加一個事件處理程式所需的DOM應用更少,所花的時間也更少。

3)、整個頁面占用的記憶體空間更少,能夠提升整體性能。

但是也要避免綁定的函數對象過大,適可而止。

事件模擬

採用js在任意時刻來觸發特定的事件,如同瀏覽器創建的事件一樣。

DOM中的事件模擬分為UIEvents、MouseEvents、MutationEvents、HTMLEvents,暫時不做詳細總結,下次待完善…

好了今天事件總結的最後一個內容了,自定義事件

事件是一種觀察者的設計模式,一種鬆散耦合代碼的技術。對象可以發佈事件,用來表示該對象生命周期中某個時刻到了。然後其他對象可以觀察該對象,等待這些時刻到來並通過運行代碼來響應。

觀察者由兩類對象組成:主體和觀察者,主體負責發佈事件,同時觀察者通過訂閱這些事件來觀察該主體。事件處理代碼便是觀察者 DOM元素則是主體,通過註冊事件進行註冊回調函數(事件處理程式)。

當代碼中存在多個部分在特定時刻相互交互的情況下,自定義事件就很有用。這時,如果每個對象都有對所有對象的引用,那麼整個代碼就會緊耦合,維護困難,因為對某個對象的修改也會影響到其他對象。使用自定義事件有助於解耦相關對象,保持功能的隔絕。很多情況中,觸發事件的代碼和監聽事件的代碼是完全分離的。

下麵給出一個代碼例子

 1 function EventTarget(){
 2     this.handlers={};
 3 }
 4 
 5 EventTarget.prototype={
 6     constructor:EventTarget,
 7     addHandler:function(type,handler){
 8         if(typeof this.handlers[type] == "undefined"){
 9             this.handlers[type]=[];
10         }
11         this.handlers[type].push(handler);
12     },
13     fire:function(event){
14         if(!event.target){
15             event.target=this;
16         }
17         if(this.handlers[event.type] instanceof Array){
18             var handlers=this.handlers[event.type];
19             for(var i=0,len=handlers.length;i<len;i++){
20                 handlers[i][event];
21             }
22         }
23 
24     },
25     removeHandler:function(type,handler){
26         if(this.handlers[type] instanceof Array){
27             var handlers=this.handlers[type];
28             for(var i=0,len=handlers.length;i<len;i++){
29                 if(handlers[i]=== handler){
30                     break;
31                 }
32             }
33             handlers.splice(i,1);
34 
35         }
36     }
37 };
View Code
 1 使用EventTarget類型的自定義事件可以如下使用:
 2 function handleMessage(event){
 3     alert("Message received:"+event.message);
 4 }
 5 //創建一個新對象
 6 var target = new EventTarget();
 7 //添加一個事件處理程式
 8 target.addHandler("message",handleMessage);
 9 //觸發事件
10 target.fire({type:"message",message:"Hello World"});
11 //刪除事件處理程式
12 target.removeHandler("message",handleMessage);
13 //再次,應沒有處理程式
14 target.fire({type:"message",message:"hello world"});
View Code

到此我所理解的事件基本上算是總結完啦,有些部分還沒有總結出來,後面有時間再做詳細的總結學習。

參考資料:

1)、《JavaScript高級程式設計》第3版

(2)、w3c:https://www.w3.org/TR/DOM-Level-3-Events/#ui-events-intro

  


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 註意 轉載須保留原文鏈接(http://www.cnblogs.com/wzhiq896/p/5935209.html)作者:wangwen896 整理 綜合類 入門類 工具類 綜合效果搜索平臺 團隊Blog|周報類 開發中心 Nodejs 綜合API Ecmascript Js template ...
  • × 目錄 [1]顯隱效果 [2]高度變化 [3]淡入淡出 前面的話 動畫效果是jQuery吸引人的地方。通過jQuery的動畫方法,能夠輕鬆地為網頁添加視覺效果,給用戶一種全新的體驗。jQuery動畫是一個大的系列,本文將詳細介紹jQuery的三種常見動畫效果——顯隱效果、高度變化及淡入淡出 顯隱 ...
  • 在項目開發時,我們時常需要考慮用戶在使用產品時產生的各種各樣的交互事件,比如滑鼠點擊事件、敲擊鍵盤事件等。這樣的事件行為都是前端DOM事件的組成部分,不同的DOM事件會有不同的觸發條件和觸發效果。本文就將帶大家深入淺出地瞭解DOM事件的那些屬性和方法。 首先在介紹DOM事件之前我們先來認識下DOM的 ...
  • 上一章有對個人作品站點進行一些優化。本章,輪到我們充實這個作品站點了,補充一些項目,從而展示我們的能力。換句話說,我們要構建一個相對複雜的企業網站主頁。 下麵有幾個成功企業的網站: □ Zappos (http://www.zappos.com/) □ Amazon (https://www.ama ...
  • 一、HTML是什麼 HTML的全稱是Hyper Text Markup Language,中譯超文本標記語言(“超文本”就是指頁面內可以包含圖片、鏈接,甚至音樂、程式等非文字元素),它是標準通用標記語言下的一個應用。 而網頁的本質就是超級文本標記語言,通過結合使用其他的Web技術(如:腳本語言、公共 ...
  • 國慶了,出去玩耍,也有好長時間沒有更新博客了。。 今天就和大家共用一篇技術博文吧。。 CSS中相容的一面 Hack技術大全 相容範圍: IE:6.0+,FireFox:2.0+,Opera 10.0+,Sarari 3.0+,Chrome 參考資料: 各游覽器常用相容標記一覽表: 標記IE6IE7I ...
  • 接上面的船舶管理業務,這裡介紹添加和修改操作。 目錄 1. 添加操作 2. 修改操作 3. 線上演示 1. 添加操作 1.1 創建AddShipWindow.js 在業務中的view目錄下創建一個AddShipWindow.js文件,表示一個增加船舶的視窗組件。 此文件中包含了一個form組件用於顯 ...
  • Atitit.gui api自動化調用技術原理與實踐 gui介面實現分類(h5,win gui, paint opengl,,swing,,.net winform,)1 Solu cate1 Solu1 other1 Ref2 gui介面實現分類(h5,win gui, paint opengl, ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...