事件
事件的概念
事件就是文檔或瀏覽器窗口中發生的一些特定的交互瞬間【觸發與響應】
事件觸發:用戶在頁面上操作(如點擊按鈕, 鼠標滑過, 鼠標點擊, 鼠標鬆開, 文本框獲得焦點, 失去焦點等)
事件觸發順序
捕獲--目標--冒泡
- 事件流
事件流是描述的從頁面接受事件的順序,當幾個都具有事件的元素層疊在一起的時候, 那麼你點擊其中一個元素,並不是只有當前被點擊的元素會觸發事件,而層疊在你點擊範圍的所有元素都會觸發事件。事件流包括兩種模式:冒泡和捕獲。 - 事件冒泡
事件冒泡是從裏往外逐個觸發. 事件捕獲, 是從外往裏逐個觸發. 現代的瀏覽器默認情況下都是事件冒泡的模式.
常用的事件類型
'on'+事件名
- 表單:
change事件---域的內容被改變
focus事件--元素獲得焦點(不冒泡)
blur事件---元素失去焦點(不冒泡)
- window事件:
load事件--頁面資源包括圖像完成加載,當頁面完全加載後觸發
resize事件---窗口改變。
scroll事件---當用戶滾動帶滾動條的元素時觸發
- 鼠標事件:
contextmenu--鼠標右鍵
click事件---單擊
mouseover事件(冒泡)---當鼠標移入某個元素的那一刻觸發
mouseenter事件(不冒泡)----當鼠標移入某個元素的那一刻觸發
mouseout事件(冒泡)---當鼠標剛移出某個元素的那一刻觸發
mouseleave事件(不冒泡)----當鼠標剛移出某個元素的那一刻觸發
mouseover和 mouseenter的區別是:
mouseover,mouseout: 元素的子元素也會觸發事件
mouseenter ,mouseleave: 元素的子元素不會觸發事件
- 鍵盤事件--一般由window對象或者document對象調用
keydown事件---某個鍵盤按鍵被按下
keyup事件----某個鍵盤按鍵被鬆開。
keypress事件----某個鍵盤按鍵被按下並鬆開。
事件的三要素:
1.事件源:要綁定事件的對象;
2.事件名稱:發生了或是綁定了什麼事件;
3.事件處理程序:要執行的函數或是要處理的結果。
事件的書寫位置:
(1) 行內式:頁面的標籤當中---不利於維護
行內式註冊事件,將事件類型當作屬性名,屬性值爲一個調用我們在js中定義好的函數。相當於函數的返回值賦給onclick
<div id="box" onclick="show()">點我</div>
<script>
function show () {
alert('點我才彈出來')
}
</script>
內聯模式調用的函數不能放到window.onload裏面, 否則會找不到該函數.
(2) 內嵌式(屬性綁定模式): 寫在script標籤之間---只能綁定一個函數
//先獲取到元素節點對象, 再針對該節點對象添加事件
var box=document.getElementById('box')
box.onclick=function(){
alert('點我才彈出來')
(3) 導入式:後面一般用的多
把代碼存放在.js文件中,導入到html文件
<sccript src="demo.js"></script>
註冊事件的方式:
<!-- 瀏覽器默認是冒泡事件 -->
(1)on+type
var oBtn = document.getElementById("btn1");
oBtn.onclick=function(){
alert('a')
}
oBtn.onclick=function(){
alert('b') //一個節點對象只能邦定一個同名事件,後面的後覆蓋掉前面的
}
(2)addEventListener:標準事件(ie不支持)
element.addEventListener('click', fn, false);
//三個參數:"事件名稱", "事件回調", "捕獲(true)/冒泡(false)"。
//FF和Chrome addEventListener(事件名,函數),此方法ie不支持
var oBtn = document.getElementById("btn1");
oBtn.addEventListener("click",function()
{
alert("a");
});
oBtn.addEventListener("click",function()
{
alert("b");
})
(3)attachEvent:僅僅ie支持
element.attachEvent('onclick', fn);
//兩個參數:"on事件名稱", "事件回調"。
var oBtn = document.getElementById("btn1");
//IE attachEvent(事件名,函數),此方法只有ie支持,FF和Chrome均不支持
oBtn.attachEvent("onclick",function()
{
alert("a");
});
oBtn.attachEvent("onclick",function()
{
alert("b");
})
兼容的寫法:
//ie只支持attachEvent,而FF和Chrome只支持addEventListener
function addEvent(obj,ev,fn)
//obj爲要綁定事件的元素,ev爲要綁定的事件,fn爲綁定事件的函數
{
if(obj.attachEvent)
{
obj.attachEvent("on" + ev,fn);
}
else
{
obj.addEventListener(ev,fn,false);
}
}
//綁定事件
addEvent(oBtn,"click",function()
{
alert("a");
})
移除事件
function removeEventListener(element,type,listener){
if(element.removeEventListener){
element.removeEventListener(type,listener,false); //標準事件
}else if(element.detachEvent){
element.detachEvent("on"+type,listener); //ie事件
}else {
element["on"+type] = null; //屬性綁定事件
}
}
事件對象(event)
event對象是在觸發事件時, 瀏覽器會通過函數把事件對象作爲參數傳遞過來, 在事件觸發執行函數時一般會得到一個隱藏的參數, 該參數也是放在arguments數組中
//普通函數的arguments
function func() {
console.log(arguments.length); //1, 得到一個傳遞的參數
}
func('hello');
//事件綁定的執行函數
box.onclick = function(){
console.log(arguments.length); //1, 得到一個隱藏參數
console.log(arguments); //數組
console.log(arguments[0]); //獲得該事件對象([object MouseEvent])
};
通過上面兩組函數中, 我們發現, 通過事件綁定的執行函數是可以得到一個隱藏參數的. 說明瀏覽器會自動分配一個參數,這個隱藏參數其實就是event對象(事件對象)
獲取事件對象
- 通過函數內部的arguments數組對象獲取
box.onclick = function(){
console.log(arguments[0]); //獲得該事件對象([object MouseEvent])
};
- 通過給函數添加一個自定義的形參(推薦)
box.onclick = function(e){
console.log(e); //[object MouseEvent]
}
event事件兼容問題:
ie不能通過傳遞的參數來獲取,需要用到全局的window.event來獲取
兼容代碼
box.onclick = function(evt){
var e= evt || window.event; //獲取到event對象(事件對象)
console.log(e);
};
其中window.event中的window可以省略, 最終我們可以寫成:
box.onclick = function(evt){
var e= evt || event; //獲取到event對象(事件對象)
console.log(e);
};
注意: evt||event不要倒過來寫
事件對象屬性
button--返回的是鼠標鍵碼(0代表鼠標左鍵,1代表鼠標滾動,2代表鼠標右鍵)
- event.clientX、event.clientY
鼠標相對於瀏覽器窗口可視區域的X,Y座標(窗口座標),會隨頁面左右滾動而改變
可視區域不包括工具欄和滾動條。IE事件和標準事件都定義了這2個屬性
- event.pageX、event.pageY
瀏覽器內容區域的x,y座標, 不會隨頁面滾動而改變
類似於event.clientX、event.clientY,但它們使用的是文檔座標而非窗口座標
這2個屬性不是標準屬性,但得到了廣泛支持。IE事件中沒有這2個屬性。
- event.offsetX、event.offsetY
鼠標相對於事件源元素(srcElement)
的X(左邊界),Y(上邊界)座標,只有IE事件有這2個屬性,標準事件沒有對應的屬性。
- event.screenX、event.screenY
事件目標對象target
目標對象,存放綁定事件的元素節點對象
標準事件對象使用 event 的 target 屬性獲取事件目標event.target
IE 事件對象使用 event 的 srcElement 屬性獲取事件目標
獲取事件目標對象兼容代碼寫法:
box.onclick = function(evt){
var e= evt || event; //獲取到event對象(事件對象)
var objEle = eve.target || eve.srcElement;//獲取事件目標對象
};
事件對象event:
1.target: 指向事件觸發的目標元素對象,第一個事件源
2.currentTarget: 事件處理函數的元素對象,始終與 this 相等;
target在事件流的目標階段;currentTarget在事件流的捕獲,目標及冒泡階段。只有當事件流處在目標階段的時候,兩個的指向纔是一樣的, 而當處於捕獲和冒泡階段的時候,target指向被單擊的對象而currentTarget指向當前事件活動的對象(一般爲父級)在事件裏面,this始終指代當前對象 始終是觸發事件的事件源 或者是始終是正在執行事件處理函數的事件源
//target等於目標節點對象(點擊的元素節點對象)鼠標點了那就是具體的目標節點對象
//currentTarget是隨着事件流,永遠等於this,
//this等於正在執行事件處理函數的事件的對象
//currentTarget指向當前事件活動的對象(跟this理解是一樣)
禁止事件冒泡。
但是一般我們只在指定的節點上添加事件, 而不想讓其傳遞到下層節點觸發事件, 這樣我們就需要阻止事件冒泡;
阻止事件冒泡有兩個方法:
( 在指定不想再繼續傳遞事件的節點的事件執行函數中使用)
1.取消冒泡, IE
e.cancelBubble = true;
- 停止傳播, 非IE
e.stopPropagation();
例如:
document.getElementsByTagName('input')[0].onclick= function(evt){
var e = evt || window.event;
//可以通過下述兩個方法取消事件冒泡
e.cancelBubble = true || e.stopPropagation();
}
阻止事件的默認行爲。
1.return false
//阻止默認的右鍵菜單
document.oncontextmenu = function(){
console.log("右鍵被按下");
return false;
}
<img src="images/placeholder.png" alt="" width="600" id="img"/>
//第一種:
<a href="images/1.jpg" onclick="turn1(this);return false;">
<img src="images/1-small.jpg" alt=""/>
</a>
var imgBox =document.getElementById("img");
function turn1(link){
imgBox.src = link.href;
}
//第二種:
<a href="images/2.jpg" onclick="return turn2(this);">
<img src="images/2-small.jpg" alt=""/>
</a>
function turn2(link){
imgBox.src = link.href;
return false;
}
//第三種:
<a href="images/3.jpg" id="link3">
<img src="images/3-small.jpg"/>
</a>
var link3=document.getElementById("link3");
link3.onclick= function () {
imgBox.src=link3.href;
return false;
}
- 標準事件對象使用 event 的 preventDefault() 方法取消事件默認行爲
event.preventDefault(); // 瀏覽器不會跳轉
3.IE 事件對象使用 event 的 returnValue 屬性取消事件默認行爲,該屬性默認值爲 true 設置爲 false 就可以取消事件默認行爲。
event.returnValue = false; // 瀏覽器不會跳轉
兼容代碼寫法:
function StopDefault(){
if(window.attachEvent){
event.returnValue = false;
}else if(window.addEventListener){
event.preventDefault();
}
}
鍵碼 : keyCode屬性
所有按鍵(包括功能鍵control, alt,shift, tab, 方向鍵等, 不包括亮度,音量..的按鍵)在發生 keydown和keyup 事件時,event對象的 keyCode屬性中會包含一個代碼,與鍵盤上一個特定的鍵對應。對數字字母字符集,keyCode屬性的值與 ASCII 碼中對應.
document.onkeydown = function(evt) {
var e = evt || event;
console.log(e.keyCode); //按任意鍵,得到相應的 keyCode
};
注意: 大寫字母或小寫的編碼相同, 都爲大寫字母。
字符編碼: charCode屬性
Firefox, Chrome和Safari的event對象支持charCode屬性, 只有按下字符鍵並且使用keypress事件時纔會得到charCode, 這個charCode的值和ASCII碼對應, 和keyCode也類似, 但是charCode的字母區分大小寫. ( 字符鍵: 數字, 字母(區分大小寫), 字符, 空格, 回車 )
document.onkeypress = function(evt) {
var e = evt || event;
console.log(e.charCode);
}
注:可以使用 String.fromCharCode()將 ASCII 編碼轉換成實際的字符