JS事件之事件類型[UI事件]

事件類型

Web瀏覽器可能發(fā)生的事件類型有很多。不同的事件類型具有不同的信息,而“DOM3級事件“規(guī)定了以下幾類事件。

  • UI(User Interface,用戶界面)事件,當用戶與頁面上的元素交互時觸發(fā);
  • 焦點事件,當元素獲得或失去焦點時觸發(fā);
  • 鼠標事件,當用戶通過鼠標在頁面執(zhí)行操作時觸發(fā);
  • 滾輪事件,當使用鼠標滾輪(或類似設置)時觸發(fā);
  • 文本事件,當在文檔中輸入文本時觸發(fā);
  • 鍵盤事件,當用戶通過包租在頁面上執(zhí)行操作時觸發(fā);
  • 合成事件,當為IME(Input MethodEditor,輸入法編輯器)輸入字符時觸發(fā);
  • 變動(mutation)事件,當?shù)讓覦OM結構發(fā)生變化時觸發(fā);
  • 變動名稱事件,當元素或屬性名變動時觸發(fā)。此類事件已經被廢棄,沒有任何瀏覽器實現(xiàn)它們,因此本章不做介紹。

除了這幾類事件之外,HTML5也定義了一組事件,而有此瀏覽器還會在DOM和BOM中實現(xiàn)其他專有事件。這些專有的事件一般都是根據開發(fā)人員需求定制的。沒有什么規(guī)范,因此不同瀏覽器的實現(xiàn)有可能不一致。
  DOM2級事件模塊在DOM2級事件模塊基礎上重新這些事件,也添加了一些新事件。包括IE9在內的所有主流瀏覽器都支持DOM2級事件。IE9也支持DOM3級事件。

UI事件

UI事件 批的是那些不一定與用戶操作有關的事件。這些事件在DOM規(guī)范出現(xiàn)之前,都是以這種或那種形式存在的。而在DOM規(guī)范中保留是為了向后兼容。現(xiàn)有的UI的事件如下.

  • DOMActivate:表示元素已經被用戶操作(通過鼠標或鍵盤)激活。這個事件在DOM3級事件中被廢棄,但FireFox2+和Chrome支持它。考慮到不同瀏覽器實現(xiàn)的差異 ,不建議使用這個事件。
  • load:當頁面完全加載后在window上面觸發(fā),當所有框架都加載完畢時在框架集上面觸發(fā),當圖像加載完畢時在<img>元素上面觸發(fā)?;蛘弋斍度氲膬热菁虞d完畢時在元素上面觸發(fā)。
  • unload:當頁面完全卸載后在window上面觸發(fā),當所有框架都卸載后在框架集上面觸發(fā),或者當嵌入的內容卸載完畢后在元素上面觸發(fā)。
  • abort:在用戶停止下載過程時,如果嵌入的內容沒有加載完,則在元素上面觸發(fā)。
  • error: 當發(fā)生JavasScript錯誤時在window上面觸發(fā),當無法加載圖片時在<img>元素上面觸發(fā),當元素加載嵌入內容時在元素上面觸發(fā),或者當有一或多個框架無法加載時在框架集上面觸發(fā)。
  • select: 當用戶選擇文本框( or )中的一個可多個字符時觸發(fā)。
  • resize: 當窗口或框架的大小變化時在window或框架上面觸發(fā);
  • scroll:當用戶流動帶有流動條的元素中的內容時,在該元素上面觸發(fā)。元素中包含所加載頁面的流動條。

多數(shù)這些事件都與window對象或表彰控件相關。

除了DOMActivate之外,其他事件都在DOM2級事件中都歸為HTML事件(DOMActivate在DOM2級中仍然屬于UI事件)。在確定瀏覽器是否支持DOM2級事件規(guī)定的HTML事件,可以使用如下代碼:

var isSupported = document.implementation.hasFeature('HTMLEvents',"2.0");

注意,只有根據“DOM2級事件”實現(xiàn)這此事件的瀏覽器才會返回true。而以非標準方式支持這些事件的瀏覽器則會返回false。要確定瀏覽器是否支持“DOM3級事件”定義的事件,可以使用如下代碼:

var isSupported = document.implementation.hasFeature('HTMLEvents',"3.0");

1、load事件

JavaScript中最常用的一個事件就是load。當頁面完全載后(包括所有圖像、JavasScript文件、CSS文件等外部資源),就會觸發(fā)window上面的load事件。有二種定義onload事件處理程序的方式。

第一種方式是使用如下所示的JavasScript代碼:

EventUtil.addHandler(window,'load', function(event){
    alert("Loaded");
})
//注意EventUtil對象是自定義封裝的一個對象

這是通過JavasScript來指定事件處理程序的方式,使用了本章前面定義的跨瀏覽器的EventUtil對象。與添加其他事件一樣,這里也給事件處理程序傳入了一個event對象。這個event對象中不包含有關這個事件的任何附加信息,但兼容DOM的瀏覽器中,event.target屬性的值會被設置為document.而IE并不會為這個事件設置srcElement屬性。

第二種指定onload事件處理程序的方式是為元素添加一個onload特性,如下面例子所示:

<body onload="alert('Loaded')">

</body>

一般來說,在window上面發(fā)生的任何事件都可以在元素中通過相應的特性來指定。因為在HTML中無法訪問window元素。初階上,這只是為了保證向后兼容的一種權宜之計,但所有瀏覽器都能很好地支持這種方式。我們建議讀者盡可能使用javascript方式。
  根據“DOM2級事件”規(guī)范,應該在document而非window上面觸發(fā)load事件,但是,所有瀏覽器都在window上面實現(xiàn)了該事件,以確保向后兼容。

圖像上面也可以觸發(fā)load事件,無論是在DOM中的圖像還是HTML中的圖像元素。 可以在HTML中為任何圖像指定onload事件處理程序,例如:

<img src="smile.gif" onload="alert('Image loaded')">

這樣,當例子中的圖像加載完畢后就會顯示一個警告框。同樣的功能也可以使用JavasScript來實現(xiàn),例如:

var image = document.getElementById('myImage');
EventUtil.addHandler(img,'load', function(evnet){
    event = EventUtil.getEvent(event);
    alert(EventUtil.getTarget(event).src);
})

這里,使用JavasScript指定了onload事件處理程序。同時民傳入了event對象,盡管它也不包含什么有用的信息。不過,事件的目標是<img>元素。可以通過src屬性訪問并顯示該 信息。

在創(chuàng)建新的<img>元素時,可以為其指定一個事件處理程序,以便圖像加載完畢后給出提示。此時,最重要在指定src屬性之前先指定事件,如下面的例子所示。

EventUtil.addHandler(window,'load', function(){
    var image = document.getElementById('myImage');

    EventUtil.addHandler(img,'load', function(){
        event = EventUtil.getEvent(event);
        alert(EventUtil.getTarget(event).src);
    });

    document.body.appendChild(image);
    image.src = 'smile.gif';
})

在這個例子中,首先為window指定了onload事件處理程序。原因在于,我們是想向DOM中添加一個新元素,所以必須確定頁面已經加載完畢——如果在頁面加載前操作document.body會導致錯誤。然后,創(chuàng)建了一個新的圖像元素,并設置了其onload事件處理程序。最后又將這個圖片添加到頁面中,還設置了它的src屬性。這里有一點需要格外注意:新圖像元素不一定要從添加到文檔后才開始下載,只要設置了src屬性就會開始下載。

同樣的功能也可以通過使用DOM0級的Image對象實現(xiàn)。在DOM出現(xiàn)之前,開發(fā)人員經常使用Image對象在客戶端預先加載圖像??梢韵袷褂?code><img>一樣使用Image對象,只不過無法將其添加到DOM樹中。下面看一個例子:

EventUtil.addHandler(window,'load', function(){
    var image = new Image();

    EventUtil.addHandler(img,'load', function(){
        alert("Image loaded!");
    });

    image.src = 'smile.gif';
})

在此,我們使用Image構造函數(shù)創(chuàng)建了一個新圖像的實例,然后又為它指定了事件處理程序。有的瀏覽器將Image對象實現(xiàn)了<img>元素,但并非所有瀏覽器都如此,所以最好將它們區(qū)別對待。
  在不屬于DOM文檔的圖像(包括未添加到文檔的元素和Image對象)上觸發(fā)load事件時,IE8及之前版本不會生成event對象。IE9修復了這個問題

還有一些元素也以非標準的方式支持load事件。在ie9+ foxfire Opera Chrome和Safari3+及更高版本中。<script>元素也會觸發(fā)load事件,以便 開發(fā)人員確定動態(tài)加載的JavasScript文件是否加載完畢。 與圖像不同,只有在設置了<script>
元素的src屬性并將該元素添加到文檔后,才會開始下載JavasScript文件。換句放說,對于元素而言,指定src屬性和指定事件處理程序的先后順序就不重要了,所有代碼展示了怎樣為<script>元素指定事件處理程序。

EventUtil.addHandler(window,'load', function(){
    var script  = document.createElement('script');
    EventUtil.addHandler(script,'load', function(){
        alert('Loaded');
    });

    script.src = "examplte.js";
    document.body.appendChild(script);
})

這個例子使用了跨瀏覽器的EventUtil對象為新創(chuàng)建的<script>元素指定了onload事件處理程序。此時,大多數(shù)瀏覽器中event對象的target屬性引用的都是<script>節(jié)點,而Foxfire3之前的版本中,引用的則是document。IE8及更早版本不支持<script>元素上的load元素。

IE和Opera還支持<link>元素上的load事件,以便開發(fā)人員確定樣式表是否加載完畢。例如:

EventUtil.addHandler(window,'load', function(){
    var link  = document.createElement('link');
    link.type="text/css";
    link.rel="stylesheet";
    EventUtil.addHandler(link,'load', function(){
        alert('css Loaded');
    });

    link.src = "examplte.css";
    document.getElementsByTagName('head')[0].appendChild(link);
})

<script>節(jié)點類似,在未指定href屬性并將<link>元素添加到文檔之前也不會開始下載樣式表。

2、unload事件

與load事件對應的是 unload事件,這個事件在文檔被完全卸載后觸發(fā)。只要用戶從一個頁面切換到另一個頁面,就會發(fā)生unload事件。而利用這個事件最多的情況是清除引用,以避免內在泄漏。與load事件類似,也兩種指定onunload事件處理程序方式。第一種方式是使用JavasScript,如下所示:

EventUtil.addHandler(window,'unload', function(){
    alert('Unloaded');
})

此時生成的event對象在兼容DOM的瀏覽器中只包含target屬性(值為document)。IE8及之前版本則為這個事件對象提供了srElement屬性。

指定事件處理程序的第二種方式,民是為<body>元素添加一個特性(與load事件相似),如下面的例子所示:

<body onunload="alert("Unloaded")"></body>

無論使用哪種方式,都要小心編寫onunload事件處理程序中的代碼。既然unload事件是在一切都被卸載后才觸發(fā) ,那么在頁面加載后存在的那些對象,此時就不一定存在了。此時,操作DOM節(jié)點或元素的樣式就會導致錯誤。

根據“DOM2級事件”,應該在<body>元素而非window對象上面觸發(fā)unload事件。不過所有瀏覽器都在window上實現(xiàn)了unload事件,以確保向后兼容。

3、resize事件

當瀏覽器窗口被調整到一個新的高度或寬度時,就會觸發(fā)resize事件。這個事件在window(窗口)上面觸發(fā),因此可以通過JavasScript或者<bdoy>元素中的onresize特性來指定事件處理程序。如前所述,我們還是推薦使用如下所示的JavasScript方式:

EventUtil.addHandler(window,'resize', function(){
    alert('Resizeed');
})

與其他發(fā)生在window上的事件類似,在兼容DOM的瀏覽器中,傳入事件處理程序中event對象有一個target屬性,值為document;而IE8及之前版本則未提供任何屬性。

關于何時會觸發(fā)resize事件,不同瀏覽器有不同的機制。IE Safari Chrome 和 Opera會在瀏覽器窗口變化了1像素時就觸發(fā) resize事件,然后隨著變化不斷重復觸發(fā)。FIrefox則只會在用戶停止調整窗口變化時才會觸發(fā) resize事件。由于 存在這個差別,應該注意不要在這個事件的處理程序中加入大計算的代碼。因為這些代碼有可能被頻繁執(zhí)行,從而導致瀏覽器反應明顯變慢。

瀏覽器窗口最小化或最大化時也會觸發(fā) resize事件

4、scroll事件

雖然scroll事件是在window對象上發(fā)生的,但它實際表示的則是頁面中相應元素的變化。在混雜模式下,可以通過 <body>元素的scrollLeft和scrollTop來監(jiān)控到這一變化;而在標準 模式下,除Safari之外的所有瀏覽器都會通過<html>元素來反映這一變化(Safari仍然基于<body>跟蹤滾動位置),如下面的例子所示:

EventUtil.addHandler(window,'scroll', function(){
    if(documnent.compatMode == 'CSS1Compat') {
        alert(document.documentElement.scrollTop);
    } else {
        alert(document.body.scrollTop);
    }
})

以上代碼指定的事件處理程序會輸出頁面的垂直滾動位置—–根據呈現(xiàn)模式不同使用了不同的元素。 由于 Safari3.1之前的版本不支持document.compatMode,因此舊版本的瀏覽器就不會滿足第二個條件。

與resize事件類似,scroll事件也會在文檔被滾動期間重復被觸發(fā),所以有必要盡量保持事件處理程序的代碼簡單。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,646評論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,595評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,560評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,814評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,224評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,444評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 48,988評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,804評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,998評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,237評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,706評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,993評論 2 374

推薦閱讀更多精彩內容

  • JavaScript 程序采用了異步事件驅動編程模型。在這種程序設計風格下,當文檔、瀏覽器、元素或與之相關的對象發(fā)...
    劼哥stone閱讀 1,272評論 3 11
  • 事件流 IE和Netscape開發(fā)團隊提出了完全相反的兩種事件流的概念,事件冒泡流和事件捕獲流。 事件冒泡 事件由...
    exialym閱讀 952評論 0 9
  • 1.幾種基本數(shù)據類型?復雜數(shù)據類型?值類型和引用數(shù)據類型?堆棧數(shù)據結構? 基本數(shù)據類型:Undefined、Nul...
    極樂君閱讀 5,555評論 0 106
  • 聲明:本文來源于http://www.webzsky.com/?p=731我只是在這里作為自己的學習筆記整理一下(...
    angryyan閱讀 7,072評論 1 6
  • 學習是一種什么樣的體驗? 學習對我來說,是醍醐灌頂?shù)淖晕翌D悟,來自更高場域的人對你說的一句話,讓你瞬間開啟了更大的...
    蔡蔡1988閱讀 434評論 0 3