js中事件物件event
一、Event物件
Event 物件代表事件的狀態,比如事件在其中發生的元素、鍵盤按鍵的狀態、滑鼠的位置、滑鼠按鈕的狀態。
事件通常與函式結合使用,函式不會在事件發生前被執行!
當一個事件發生的時候,和當前這個物件發生的這個事件有關的一些詳細資訊(包括導致事件的元素、事件的型別、以及其它與特定事件相關的資訊等。這個物件是在執行事件時,瀏覽器通過函式傳遞過來的。)都會被臨時儲存到一個指定的地方——event物件,供我們在需要的時候呼叫
二、獲取event物件
在 W3C 規範中,event 物件是隨事件處理函式傳入的,Chrome、FireFox、Opera、Safari、IE9.0及其以上版本都支援這種方式;但是對於 IE8.0 及其以下版本,event 物件必須作為 window 物件的一個屬性。
IE、Chrome:event是一個內建的全域性物件
標準下/FF:事件物件是通過事件函式的第一個引數傳入(如果一個函式是被事件呼叫的,那麼這個函式定義的第一個引數就是事件物件)
如何處理相容性:
document.onclick = function fn(){
var ev = ev||event;
alert('處理相容');
}
例子:
<script>
window.onload = function(){
var oDiv = document.getElementById('div1');
document.onmousemove = function(ev){
var ev = ev||event;//處理相容性
oDiv.style.left = ev.clientX + 'px';
oDiv.style.top = ev.clientY + 'px';
}
}
</script>
三、事件流
事件流是描述的從頁面接受事件的順序,當幾個都具有事件的元素層疊在一起的時候而層疊在你點選範圍 , 並不是只有當前被點選的元素會觸發事件 , 那麼你點選其中一個元素的所有元素都會觸發事件。而如果我們想要只觸發其中一個事件時,此時就需要取消冒泡或捕獲。現代瀏覽器預設都是冒泡型別,所以通常只需要取消冒泡即可。
事件流包括兩種模式:冒泡和捕獲。
1、冒泡:從裡向外逐個觸發。當你使用事件冒泡時,子級元素先觸發,父級元素後觸發
事件冒泡機制:當一個元素接收到事件的時候,會把他接收的所有傳播給他的父級,一直到頂層window
2、捕獲:從外向裡逐個觸發(與事件冒泡機制相反)當你使用事件捕獲時,父級元素先觸發,子級元素後觸發
W3C模型
W3C模型是將兩者進行中和,在W3C模型中,任何事件發生時,先從頂層開始進行事件捕獲,直到事件觸發到達了事件源元素。然後,再從事件源往上進行事件冒泡,直到到達document。
阻止事件冒泡的方法
function stopBubble(e) {
if(e && e.stopPropagation){
e.stopPropagation(); //非IE下
} else {
window.event.cancelBubble = true; //IE下
}
};
四、js事件繫結
要想讓 JavaScript 對使用者的操作作出響應,首先要對 DOM 元素繫結事件處理函式。所謂事件處理函式,就是處理使用者操作的函式,不同的操作對應不同的名稱。
在JavaScript中,有三種常用的繫結事件的方法:
- 在DOM元素中直接繫結;
- 在JavaScript程式碼中繫結;
- 繫結事件監聽函式。
1、在DOM中直接繫結
<button onclick="open()">按鈕</button>
<script>
function open(){
alert(1);
}
</script>
2、在js程式碼中繫結
<button id="btn">按鈕</button>
document.getElementById('btn').onclick = function(){
this.style.background = 'yellow';
}
3、繫結事件監聽函式
繫結事件的另一種方法是用 addEventListener() 或 attachEvent() 來繫結事件監聽函式。
addEventListener()函式語法:
elementObject.addEventListener(eventName,handle,useCapture);
引數 | 說明 |
---|---|
elementObject | DOM物件(即DOM元素)。 |
eventName | 事件名稱。注意,這裡的事件名稱沒有“ on ”,如滑鼠單擊事件 click ,滑鼠雙擊事件 doubleclick ,滑鼠移入事件 mouseover,滑鼠移出事件 mouseout 等。 |
handle | 事件控制程式碼函式,即用來處理事件的函式。 |
useCapture | Boolean型別,是否使用捕獲,一般用false 。這裡涉及到JavaScript事件流的概念,前面已經進行了講解 |
attachEvent()函式語法:
elementObject.attachEvent(eventName,handle);
引數 | 說明 |
---|---|
elementObject | DOM物件(即DOM元素)。 |
eventName | 事件名稱。注意,與addEventListener()不同,這裡的事件名稱有“ on ”,如滑鼠單擊事件 onclick ,滑鼠雙擊事件 ondoubleclick ,滑鼠移入事件 onmouseover,滑鼠移出事件 onmouseout 等。 |
handle | 事件控制程式碼函式,即用來處理事件的函式。 |
注意:事件控制程式碼函式是指“ 函式名 ”,不能帶小括號。
addEventListener()是標準的繫結事件監聽函式的方法,是W3C所支援的,Chrome、FireFox、Opera、Safari、IE9.0及其以上版本都支援該函式;但是,IE8.0及其以下版本不支援該方法,它使用attachEvent()來繫結事件監聽函式。所以,這種繫結事件的方法必須要處理瀏覽器相容問題。
下面繫結事件的程式碼,進行了相容性處理,能夠被所有瀏覽器支援:
<button id="btn">按鈕</button>
<script type="text/javascript">
var oBtn = document.getElementById('btn');
function addEvent(obj,type,handle){
try{ // Chrome、FireFox、Opera、Safari、IE9.0及其以上版本
obj.addEventListener(type,handle,false);
}catch(e){
try{ // IE8.0及其以下版本
obj.attachEvent('on' + type,handle);
}catch(e){ // 早期瀏覽器
obj['on' + type] = handle;
}
}
}
addEvent(oBtn,'click',function(){//切記cliclk要加引號,沒加會報錯
this.style.width = 200+'px';
});
</script>
<span style="color:#ffcc33">這裡使用 try{ ... } catch(e){ ... } 代替 if ... else... 語句,避免瀏覽器出現錯誤提示。</span>
注意:obj.addEventListener('click',fn,true);(從外到裡)//告訴Obj,如果有一個進去的事件觸發了你,你就去執行fn這個函式 obj.addEventListeren('click',fn,false);(從裡到外)//告訴Obj,如果有一個出去的事件觸發了你,你就去執行fn這個函式
總結一下就是:如果最後一個布林值引數是true,就表示,在捕獲階段呼叫事件處理程式,如果是false,就表示在冒泡階段呼叫事件處理程式
4、三種繫結事件的區別
第一種方式:函式寫在結構層裡面。非常不好,使頁面很混亂,行為與結構得不到分離。並且在DOM結構如果繫結兩個 "onclick" 事件,只會執行第一個;
第二種方式:行為與結構開始分離。第二種繫結方式中只能給一個時間繫結一個處理函式,在指令碼通過匿名函式的方式繫結的只會執行最後一個事件。
第三種方式:可以繫結多次同一個事件,且都會執行
1. <div id="btn" onclick="clickone()" onclick="clicktwo()"></div>
<script>
function clickone(){ alert("hello"); } //執行這個
function clicktwo(){ alert("world!"); }
</script>
2. <div id="btn"></div>
<script>
document.getElementById("btn").onclick = function(){ alert("hello"); }
document.getElementById("btn").onclick = function(){ alert("world"); } //執行這個
</script>
3. <div id="btn"></div>
<script>
document.getElementById("btn").addeventlistener("click",clickone,false);
function clickone(){ alert("hello"); } //先執行
document.getElementById("btn").addeventlistener("click",clicktwo,false);
function clicktwo(){ alert("world"); } //後執行
</script>
5、如何取消事件繫結
第一種方式:document.onclick = null;(針對第一和第二兩種繫結方式)
第二種方式:obj.detachEvent(事件名稱,事件函式);(針對非標準IE下的繫結方式)
第三種方式:obj.removeEventListener(事件名稱,事件函式,是否捕獲);(針對標準瀏覽器下的繫結方式)
五、js事件委託
事件委託:利用事件冒泡的特性,將裡層的事件委託給外層事件,根據event物件的屬性進行事件委託,改善效能。
使用事件委託能夠避免對特定的每個節點新增事件監聽器;事件監聽器是被新增到它們的父元素上。事件監聽器會分析從子元素冒泡上來的事件,找到是哪個子元素的事件。(事件委託看起來挺難理解,但是舉個生活的例子。比如,有三個同事預計會在週一收到快遞。為簽收快遞,有兩種辦法:一是三個人在公司門口等快遞;二是委託給前臺MM代為簽收。)
<ul id="ul-item">
<li class="item">item1</li>
<li class="item">item2</li>
<li class="item">item3</li>
<li class="item">item4</li>
</ul>
<script type="text/javascript">
function fn(){
var oUlItem = document.getElementById('ul-item');
oUlItem.addEventListener('click',show,false);//新增監聽事件
function show(ev){
var ev = ev || window.event;
var src = ev.target||ev.srcElement;//相容IE下和FF下以及其他瀏覽器
if(src && src.className.toLowerCase() === 'item'){//tolowerCase,將字串全部轉化為小寫字母
alert(src.innerHTML);
}
}
};
fn();
</script>
以下為補充知識(js的event.srcElement與event.target(觸發事件源))
IE下,event物件有srcElement屬性,但是沒有target屬性;
Firefox下,event物件有target屬性,但是沒有srcElement屬性.但他們的作用是相當的,即:
firefox 下的 event.target = IE 下的 event.srcElement
解決方法:使用obj = event.srcElement ? event.srcElement : event.target;
或:var evtTarget = event.target || event.srcElement;
js將html的所有控制元件都看成是一個個物件,通過js的各個屬性,就能對其進行操作處理,js裡物件的整體結構是樹形的結構。一層一層的追溯,即可獲取需要的結果。
event.srcElement:表示的當前的這個事件源。
event.srcElement.parentNode:表示當前事件源的父節點。
parentNode:父節點,也就是上一層的節點。可以是任何一個標籤。
event.srcElement.firstChild:當前事件的第一個節點,如果節點是input,通過event.srcElement.firstChild.value就可以獲取此input的值。
event.srcElement.parentElement:是指在滑鼠所在物件的上一個物件。
event.srcElement.children:當前節點下物件的個數,有多個的話就是個陣列,如當前節點下有2個input的物件,要獲取這兩個可以用event.srcElement.children[0] 與 event.srcElement.children[1]分別獲取。
相關文章
- JS中event事件JS事件
- JS 事件機制 Event LoopJS事件OOP
- JS事件迴圈Event LoopJS事件OOP
- JS 事件迴圈(Event Loop)JS事件OOP
- js 在瀏覽器中的event loop事件佇列JS瀏覽器OOP事件佇列
- jQuery事件物件event的屬性和方法jQuery事件物件
- JavaScript 複習之 事件模型 和 Event物件JavaScript事件模型物件
- Node.js Event Loop與瀏覽器 Event Loop(事件環)Node.jsOOP瀏覽器事件
- 淺談js的事件迴圈(Event Loop)JS事件OOP
- JS的事件物件與事件機制JS事件物件
- 和我一起理解js中的事件物件JS事件物件
- 淺談Node.js的事件環(event loop)Node.js事件OOP
- node中的事件環(Event Loop)事件OOP
- Event Handler 事件處理程式 2 —跨瀏覽器事件物件《高程3》事件瀏覽器物件
- 理解瀏覽器和node.js中的Event loop事件迴圈瀏覽器Node.jsOOP事件
- mysql 事件 eventMySql事件
- Laravel 中的 Event 和事件的概念Laravel事件
- nodejs中的事件迴圈 - Event LoopNodeJS事件OOP
- MySQL中的事件排程器EVENTMySql事件
- Spring中的事件講解(Application Event)Spring事件APP
- 效能優化篇 - js事件迴圈機制(event loop)優化JS事件OOP
- Vue.js原始碼學習三 —— 事件 Event 學習Vue.js原始碼事件
- [譯]理解js中的event loopJSOOP
- Node.js 中的 Event loopNode.jsOOP
- 淺析 JS 中的 Event LoopJSOOP
- Tkinter (44) 事件 Event事件
- Laravel使用event事件Laravel事件
- Node.js中的事件迴圈(Event Loop),計時器(Timers)以及process.nextTick()Node.js事件OOP
- 【譯】Node.js中的Event LoopNode.jsOOP
- 理解JS中的Event Loop機制JSOOP
- HTML DOM Event 物件HTML物件
- (精華2020年5月4日更新) vue教程篇 事件簡寫和事件物件$eventVue事件物件
- Dynamics 365中的事件框架與事件執行管道(Event execution pipeline)事件框架
- Javascript中的事件物件和事件型別JavaScript事件物件型別
- MySQL入門--EVENT(事件)MySql事件
- Spring Boot 之事件(Event)Spring Boot事件
- 事件迴圈(event loop)事件OOP
- Js中Math物件JS物件