JavaScript 事件簡介

事件

事件的概念

事件就是文檔或瀏覽器窗口中發生的一些特定的交互瞬間【觸發與響應】
事件觸發:用戶在頁面上操作(如點擊按鈕, 鼠標滑過, 鼠標點擊, 鼠標鬆開, 文本框獲得焦點, 失去焦點等)

事件觸發順序

捕獲--目標--冒泡

  • 事件流
    事件流是描述的從頁面接受事件的順序,當幾個都具有事件的元素層疊在一起的時候, 那麼你點擊其中一個元素,並不是只有當前被點擊的元素會觸發事件,而層疊在你點擊範圍的所有元素都會觸發事件。事件流包括兩種模式:冒泡和捕獲。
  • 事件冒泡
    事件冒泡是從裏往外逐個觸發. 事件捕獲, 是從外往裏逐個觸發. 現代的瀏覽器默認情況下都是事件冒泡的模式.

常用的事件類型

'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;
  1. 停止傳播, 非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;
    }
  1. 標準事件對象使用 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 編碼轉換成實際的字符

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章