1. 程式人生 > >深入理解DOM事件機制系列第三篇——事件物件

深入理解DOM事件機制系列第三篇——事件物件

前面的話

  在觸發DOM上的某個事件時,會產生一個事件物件event,這個物件中包含著所有與事件有關的資訊。所有瀏覽器都支援event物件,但支援方式不同。本文將詳細介紹事件物件

獲取事件物件

  【1】一般地,event物件是事件程式的第一個引數

  [注意]IE8-瀏覽器不支援

複製程式碼
//IE8-瀏覽器輸出undefined,其他瀏覽器則輸出事件物件[object MouseEvent]
<div id="box" style="height:30px;width:200px;background:pink;"></div>
<script>
var oBox 
= document.getElementById('box'); oBox.onclick = function(a){ box.innerHTML = a; } </script>
複製程式碼

  【2】另一種方法是直接使用event變數

  [注意]firefox瀏覽器不支援

複製程式碼
//firefox瀏覽器輸出undefined,其他瀏覽器則輸出事件物件[object MouseEvent]  
<div id="box" style="height:30px;width:200px;background:pink;"></div>
<script>
var oBox = document.getElementById('box'); oBox.onclick = function(){ box.innerHTML = event; } </script>
複製程式碼

相容

  於是,對於獲取事件物件的常見相容寫法如下

複製程式碼
<div id="box" style="height:30px;width:200px;background:pink;"></div>
<script>
var oBox = document.getElementById('box');
oBox.onclick = function
(e){ e = e || event; box.innerHTML = e; } </script>
複製程式碼

屬性和方法

  事件物件包含與建立它的特定事件有關的屬性和方法。觸發的事件型別不一樣,可用的屬性和方法也不一樣。不過,所有事件都有些共有的屬性和方法

事件型別

  事件有很多型別,事件物件中的type屬性表示被觸發的事件型別

複製程式碼
<div id="box" style="height:30px;width:200px;background:pink;"></div>
<script>
//滑鼠移入時,顯示mouseover;移出時,顯示mouseout;點選時,顯示click
var oBox = document.getElementById('box');
oBox.onclick = oBox.onmouseout =oBox.onmouseover =function(e){
    e = e || event;
    box.innerHTML = e.type;
}
</script>
複製程式碼

  通過點選或按tab鍵將焦點切換到button按鈕上可以觸發focus事件

複製程式碼
<button id="box" style="height:30px;width:200px;background:pink;"></button>
<script>
var oBox = document.getElementById('box');
oBox.onfocus = function(e){
    e = e || event;
    box.innerHTML = e.type;
}
</script>
複製程式碼

事件目標

  關於事件目標,共有currentTarget、target和srcElement這三個屬性

currentTarget

  currentTarget屬性返回事件當前所在的節點,即正在執行的監聽函式所繫結的那個節點

  [注意]IE8-瀏覽器不支援

  一般地,currentTarget與事件中的this指向相同。但在attachEvent()事件處理程式中,this指向window,詳細資訊移步至此

複製程式碼
<style>
.in{height: 30px;background-color: lightblue;margin:0 10px;}
</style>
<ul id="box">
    <li class="in">1</li>
    <li class="in">2</li>
</ul>
<script>
box.onclick = function(e){
    e = e || event;
    var tags =  box.getElementsByTagName('li');
    tags[0].innerHTML = e.currentTarget;
    tags[1].innerHTML = (e.currentTarget === this);
}
</script>
複製程式碼

target

  currentTarget屬性返回事件正在執行的監聽函式所繫結的節點,而target屬性返回事件的實際目標節點

  [注意]IE8-瀏覽器不支援

  以下程式碼中,點選該實際目標節點時,顏色變品紅;移出時,顏色變淺藍

複製程式碼
<style>
#box{background-color: lightblue;}
.in{height: 30px;}
</style>
<ul id="box">
    <li class="in">1</li>
    <li class="in">2</li>
</ul>
<script>
box.onclick = function(e){
    e = e || event;
    e.target.style.backgroundColor = 'pink';
}
box.onmouseout = function(e){
    e = e || event;
    e.target.style.backgroundColor = 'lightblue';
}
</script>
複製程式碼

srcElement

  srcElement屬性與target屬性功能一致

  [注意]firefox瀏覽器不支援

複製程式碼
<style>
#box{background-color: lightblue;}
.in{height: 30px;}
</style>
<ul id="box">
    <li class="in">1</li>
    <li class="in">2</li>
</ul>
<script>
box.onclick = function(e){
    e = e || event;
    e.srcElement.style.backgroundColor = 'pink';
}
box.onmouseout = function(e){
    e = e || event;
    e.srcElement.style.backgroundColor = 'lightblue';
}
</script>
複製程式碼

相容 

var handler = function(e){
    e = e || event;
    var target = e.target || e.srcElement;
}

事件代理

  由於事件會在冒泡階段向上傳播到父節點,因此可以把子節點的監聽函式定義在父節點上,由父節點的監聽函式統一處理多個子元素的事件。這種方法叫做事件的代理(delegation),也叫事件委託

  事件代理應用事件目標的target和srcElement屬性完成。利用事件代理,可以提高效能及降低程式碼複雜度

  有一個需求,一個<ul>中有5個<li>,移入時變淺藍,移出時變品紅

  下面分別用常規方法和事件代理方法來實現

複製程式碼
<style>
#box{background-color: pink;}
.in{height: 30px;}
</style>
<ul id="box">
    <li class="in">1</li>
    <li class="in">2</li>
    <li class="in">3</li>
    <li class="in">4</li>
    <li class="in">5</li>
</ul>
<script>
//常規方法
var tags = box.getElementsByTagName('li');
for(var i = 0; i < tags.length; i++){
    tags[i].onmouseover = function(e){
        this.style.backgroundColor = 'lightblue';
    }
    tags[i].onmouseout = function(e){
        this.style.backgroundColor = 'pink';
    }
}
</script>

<script>
//事件代理方法
box.onmouseover = function(e){
    e = e || event;
    var target = e.target || e.srcElement;
    target.style.backgroundColor = 'lightblue';
}
box.onmouseout = function(e){
    e = e || event;
    var target = e.target || e.srcElement;
    target.style.backgroundColor = 'pink';
}
</script>
複製程式碼

  如果可行的話,也可以考慮為document新增一個事件處理程式,用以處理頁面上發生的某種特定型別的事件。這樣做與採取傳統的做法相比有以下優點:

  1、document物件很快就可以訪問,而且可以在頁面生命週期的任何時間點上為它新增事件處理程式,而無需等待DOMContentLoadedload事件。換句話說,只要可單擊的元素呈現在頁面上,就可以立即具備適當的功能

  2、在頁面中設定事件處理程式所需的時間更少。只新增一個事件處理程式所需的DOM引用更少,所花的時間也更少

  3、整個頁面佔用的記憶體空間更少,能夠提升整體效能

  最適合使用事件委託技術的事件包括click、mousedown、mouseup、keydown、keyup和keypress

事件冒泡

  事件冒泡是事件流的第三個階段,通過事件冒泡可以在這個階段對事件做出響應

  關於冒泡,事件物件中包含bubbles、cancelBubble、stopPropagation()和stopImmediatePropagation()這四個相關的屬性和方法

bubbles

  bubbles屬性返回一個布林值,表示當前事件是否會冒泡。該屬性為只讀屬性

  發生在文件元素上的大部分事件都會冒泡,但focus、blur和scroll事件不會冒泡。所以,除了這三個事件bubbles屬性返回false外,其他事件該屬性都為true

複製程式碼
<button id="test" style="height: 30px;width: 200px;"></button>
<script>
//點選按鈕時,按鈕內容為true,說明click事件預設可冒泡
test.onclick = function(e){
    test.innerHTML =e.bubbles;//true
}
</script>
複製程式碼 複製程式碼
<div id="test" style="height: 50px;width: 200px;overflow:scroll;background:pink;line-height:60px;">內容</div>
<script>
//滾動時,div內容變成false,說明scroll事件預設不可冒泡
test.onscroll = function(e){
    test.innerHTML =e.bubbles;//false
}
</script>
複製程式碼

stopPropagation()

  stopPropagation()方法表示取消事件的進一步捕獲或冒泡,無返回值

  [注意]IE8-瀏覽器不支援

複製程式碼
<button id="test" style="height: 30px;width: 200px;"></button>
<script>
//點選按鈕時,按鈕內容為'button',因為阻止了<button>向<body>的冒泡
test.onclick = function(e){
    e = e || event;
    e.stopPropagation();
    test.innerHTML +='button\n';
}
document.body.onclick = function(e){
    test.innerHTML += 'body\n'
}
</script>
複製程式碼

stopImmediatePropagation()

  stopImmediatePropagation()方法不僅可以取消事件的進一步捕獲或冒泡,而且可以阻止同一個事件的其他監聽函式被呼叫,無返回值

  [注意]IE8-瀏覽器不支援

  使用stopIPropagation()方法,可以阻止冒泡,但無法阻止同一事件的其他監聽函式被呼叫

複製程式碼
<button id="test" style="height: 30px;width: 200px;"
            
           

相關推薦

深入理解DOM事件機制系列——事件物件

前面的話   在觸發DOM上的某個事件時,會產生一個事件物件event,這個物件中包含著所有與事件有關的資訊。所有瀏覽器都支援event物件,但支援方式不同。本文將詳細介紹事件物件 獲取事件物件   【1】一般地,event物件是事件程式的第一個引數   [注意

深入理解DOM事件機制系列——事件模擬

前面的話   事件是網頁中某個特別的瞬間,經常由使用者操作或通過其他瀏覽器功能來觸發。但實際上,也可以使用javascript在任意時刻來觸發特定的事件,而此時的事件就如同瀏覽器建立的事件一樣。本文將詳細介紹事件模擬 引入   以下面的實際需求為例,來詳細說明事

深入理解javascript作用域系列

彈出 例子 深入理解java logs title 最終 pre 有變 context 前面的話   對於執行環境(execution context)和作用域(scope)並不容易區分,甚至很多人認為它們就是一回事,只是高程和犀牛書關於作用域的兩種不同翻譯而已。但實際上,

深入學習jQuery選擇器系列——過濾選擇器之索引選擇器

通用形式$(':eq(index)')  $(':eq(index)')選擇器選擇索引等於index的元素(index從0開始),返回單個元素索引  [注意]索引選擇器的索引和子元素選擇器的索引有明顯的不同  【1】索引選擇器索引從0開始,而子元素選擇器索引從1開始  【2】索引選擇器的索引是指定元素的索引,

深入理解javascript作用域系列——一張圖理解執行環境和作用域

前面的話   對於執行環境(execution context)和作用域(scope)並不容易區分,甚至很多人認為它們就是一回事,只是高程和犀牛書關於作用域的兩種不同翻譯而已。但實際上,它們並不相同,卻相互糾纏在一起。本文先用一張圖開宗明義,然後進行術語的簡單解釋,最後根據圖示內容進行詳細說明 圖示

深入理解定時器系列——定時器應用(時鐘、倒計時、秒錶和鬧鐘)

前面的話   本文屬於定時器的應用部分,分別用於實現與時間相關的四個應用,包括時鐘、倒計時、秒錶和鬧鐘。與時間相關需要用到時間和日期物件Date,詳細情況移步至此 時鐘   最簡單的時鐘製作辦法是通過正則表示式的exec()方法,將時間物件的字串中的時間部分截取出來,使用定時器重新整理即可 &

深入理解javascript函式進階系列——函式節流和函式防抖

前面的話   javascript中的函式大多數情況下都是由使用者主動呼叫觸發的,除非是函式本身的實現不合理,否則一般不會遇到跟效能相關的問題。但在一些少數情況下,函式的觸發不是由使用者直接控制的。在這些場景下,函式有可能被非常頻繁地呼叫,而造成大的效能問題。解決效能問題的處理辦法就是函式節流和函式防抖。本

深入理解javascript物件系列——神祕的屬性描述符

前面的話   對於作業系統中的檔案,我們可以駕輕就熟將其設定為只讀、隱藏、系統檔案或普通檔案。於物件來說,屬性描述符提供類似的功能,用來描述物件的值、是否可配置、是否可修改以及是否可列舉。本文就來介紹物件中神祕的屬性描述符 描述符型別   物件屬性描述符的型別分為兩種:資料屬性和訪問器屬性 資料屬

深入理解ajax系列——響應解碼

前面的話   我們接收到的響應主體型別可以是多種形式的,包括字串String、ArrayBuffer物件、二進位制Blob物件、JSON物件、javascirpt檔案及表示XML文件的Document物件等。下面將針對不同的主體型別,進行相應的響應解碼 屬性   在介紹響

深入理解javascript選擇器API系列——HTML5新增的3種selector方法

前面的話  儘管DOM作為API已經非常完善了,但是為了實現更多的功能,DOM仍然進行了擴充套件,其中一個重要的擴充套件就是對選擇器API的擴充套件。人們對jQuery的稱讚,很多是由於jQuery方便的元素選擇器。除了前面已經介紹過的getElementsByClassNa

讀書筆記 ---- 《深入理解Java虛擬機器》---- 6:虛擬機器類載入機制

上一篇:類檔案結構:https://blog.csdn.net/pcwl1206/article/details/84197219 第6篇:虛擬機器類載入機制 1、概述 上一篇文章中講訴了Class檔案儲存格式的具體細節,在Class檔案中的描述的各種資訊,最終都要載入到虛擬機器中之後才

CSAPP深入理解計算機系統(第二版)章家庭作業答案

《深入理解計算機系統(第二版)》CSAPP 第三章 家庭作業 這一章介紹了AT&T的彙編指令 比較重要 本人完成了《深入理解計算機系統(第二版)》(以下簡稱CSAPP)第三章的家庭作業,並與網上的一些答案進行了對比修正。 感謝博主summerhust的整理,以下貼出AT&T常用匯編指令

[深入理解Android卷二 全文-章]深入理解SystemServer

由於《深入理解Android 卷一》和《深入理解Android卷二》不再出版,而知識的傳播不應該因為紙質媒介的問題而中斷,所以我將在CSDN部落格中全文轉發這兩本書的全部內容 第3章  深入理解SystemServer本章主要內容:·  分析SystemServer·  分析

[深入理解Android卷一全文-章]深入理解init

由於《深入理解Android 卷一》和《深入理解Android卷二》不再出版,而知識的傳播不應該因為紙質媒介的問題而中斷,所以我將在CSDN部落格中全文轉發這兩本書的全部內容。第3章  深入理解init本章主要內容·  深入分析init。本章涉及的原始碼檔名及位置下面是本章分

深入理解Java的Annotation系列-四部分 註解的應用-使用註解實現許可權管理

一、整體思路 1、先自定義一個用於許可權管理的註解 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Authority {      String modu

深入理解計算機系統家庭作業

/* ***3.54 ***寫出decode2的原型*/ int decode2(int x ,int y, int z) { int a = z - y; int b = (a << 15) >> 15; return (x ^ a) *

深入理解Java的Annotation系列-五部分 使用註解編寫ORM框架

一、什麼是ORM? 物件關係對映(英語:(Object Relational Mapping,簡稱ORM,或O/RM,或O/Rmapping),是一種程式技術,隨著面向物件的發展而產生的。用來把物件模型表示的物件對映到基於S Q L 的關係模型資料庫結構中去,或者把表中的

javascript面向對象系列——實現繼承的3種形式

編程語言 urn ash yahoo 實現 經典 ray obj 學習 前面的話   學習如何創建對象是理解面向對象編程的第一步,第二步是理解繼承。開宗明義,繼承是指在原有對象的基礎上,略作修改,得到一個新的對象。javascript主要包括類式繼承、原型繼承和拷貝繼承這

讀書筆記 ---- 《深入理解Java虛擬機器》---- 7:虛擬機器位元組碼執行引擎

上一篇:虛擬機器類載入機制:https://blog.csdn.net/pcwl1206/article/details/84260914 第7篇:虛擬機器位元組碼執行引擎 執行引擎是Java虛擬機器最核心的組成部分之一。“虛擬機器”是一個相對於“物理機”的概念,這兩種機器都有程式碼執行能力

讀書筆記 ---- 《深入理解Java虛擬機器》---- 5:類檔案結構

上一篇:虛擬機器效能監控與故障處理工具:https://blog.csdn.net/pcwl1206/article/details/84197113 第5篇:類檔案結構 開篇說明:本文的重點就是類檔案結構,只需要清楚Class檔案格式中的各名稱的實際意義就行,不用對具體名稱下的細節進行深究