DOM事件

一、事件

跟用戶交互時,dom結(jié)構(gòu)發(fā)不發(fā)生改變,此時就用到事件了。
事件是當(dāng)用戶對瀏覽器進(jìn)行點擊某個地方都可能觸發(fā)任何一個事件,如用戶鼠標(biāo)單擊時、 鼠標(biāo)移動到元素上。

二、事件流

1.事件冒泡模型

事件開始時由最具體的元素接收,然后逐級向上傳播到較為不具體的元素,也就是說
從里向外

.jpg

2.事件捕獲模型

從外向里

3.DOM事件流模型

先捕獲,在冒泡

三、使用方式

DOM0

事件處理程序
也稱事件偵聽器,當(dāng)用戶或瀏覽器自身執(zhí)行了某個事件,而響應(yīng)某個事件就叫事件處理程序

1.js指定事件

<input id="btnClick" type="button" value="Click Here" />

<script type="text/javascript">
    var btnClick = document.getElementById('btnClick');
    btnClick.onclick = function showMessage() {//元素.事件=事件處理函數(shù) ()    //onclick也可是其他事件名稱
        alert(this.id);
    };
</script>
 //如果是多個相同事件注冊用這種方式,最后一個執(zhí)行,之前的被覆蓋了

(2)對一個元素綁定多個事件函數(shù) (注:會發(fā)生覆蓋)

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <button id="btn">click me</button>
</body>
</html>
<script>
var btn = document.querySelector('#btn')
//#事件01
btn.onclick = function(){
console.log(this)
console.log(this.innerText)
}
//#事件02
 btn.onclick = function(){
  console.log('hello world')
}
</script>
事件01被覆蓋
DOM2事件處理程序

DOM2級事件定義了兩個方法用于處理指定和刪除事件處理程序的操作:

  • addEventListener
  • removeEventListener
    所有的DOM節(jié)點都包含這兩個方法,并且它們都接受三個參數(shù)
    1.事件類型
    2.事件處理方法
    3.布爾參數(shù),如果是true表示在捕獲階段調(diào)用事件處理程序,如果是false,則是在事件冒泡階段處理
綁定事件

addEventListener

為同一個元素綁定多個相同的事件:

綁定事件的兩個屬性:
- 對象.addEventListener("事件類型",事件處理函數(shù),false);--谷歌和火狐支持,IE8不支持
- 對象.attachEvent("有on的事件類型(如:onclick)",事件處理函數(shù))--谷歌不支持,火狐不支持,IE8支持


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>title</title>
</head>
<body>
<input type="button" value="按鈕" id="btn"/>
</body>
<script>
如:
第一種:
//為按鈕綁定點擊事件
  //參數(shù)1:事件的類型----事件的名字,沒有on
  //參數(shù)2:事件處理函數(shù)----函數(shù)(命名函數(shù),匿名函數(shù))
  //參數(shù)3:布爾類型----默認(rèn)是事件冒泡(false),事件捕獲(true)
function btn$(id) {
    return document.getElementById(id);
}
 btn$("btn").addEventListener("click",function () {
   console.log("呵呵");
 },false);//默認(rèn)是false,可寫可不寫
 btn$("btn").addEventListener("click",function () {
   console.log("哈哈");
 },false);
 btn$("btn").addEventListener("click",function () {
   console.log("哦哦");
 },false);
 btn$("btn").addEventListener("click",function () {
   console.log("諤諤");
 },false);

第二種:
//參數(shù)1:事件類型---事件名字,有on
//參數(shù)2:事件處理函數(shù)---函數(shù)(命名函數(shù),匿名函數(shù))
function btn$(id) {
    return document.getElementById(id);
}
btn$("btn").attachEvent("onclick",function () {
  console.log("諤諤");
 });
 btn$("btn").attachEvent("onclick",function () { 
 console.log("哦哦");
 });
btn$("btn").attachEvent("onclick",function () {
   console.log("哈哈");
 });
//JavaScript指定事件的事件是:onclick,DOM2事件處理程序的事件是:click
</script>

沒有發(fā)生覆蓋


沒有發(fā)生覆蓋
總結(jié):總結(jié)綁定事件的區(qū)別:
  • addEventListener();
  • attachEvent()
  • 相同點: 都可以為元素綁定事件
  • 不同點:
  • 1.方法名不一樣
  • 2.參數(shù)個數(shù)不一樣addEventListener三個參數(shù),attachEvent兩個參數(shù)
  • 3.addEventListener 谷歌,火狐,IE11支持,IE8不支持
  • attachEvent 谷歌火狐不支持,IE11不支持,IE8支持
  • 4.this不同,addEventListener 中的this是當(dāng)前綁定事件的對象
  • attachEvent中的this是window
  • 5.addEventListener中事件的類型(事件的名字)沒有on
  • attachEvent中的事件的類型(事件的名字)有on
為按鈕綁定多個點擊事件
function btn$(id) {
    return document.getElementById(id);
}
  btn$("btn").addEventListener("click",function () {
  console.log(this);
  },false);
  btn$("btn").attachEvent("onclick",function () {
   console.log(this);
 });
如何解綁事件(一般情況下不做)

removeEventListener
removeEventListener不能使用匿名函數(shù)(無法獲知要移除誰)
如:

<script type="text/javascript">
    var btnClick = document.getElementById('btnClick');
    var handler=function() {
        alert(this.id);
    }
    btnClick.removeEventListener('click', handler, false);
</script>

四、演示

冒泡階段與阻止冒泡
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>title</title>
  <style>
    #dv1{
      width: 300px;
      height: 200px;
     border: 1px solid ;
    }
    #dv2{
      width: 250px;
      height: 150px;
     border: 1px solid ;
    }
    #dv3{
      width: 200px;
      height: 100px;
      border: 1px solid ;
    }
  </style>
</head>
<body>
<div id="dv1">a
  <div id="dv2">b
    <div id="dv3">c</div>
  </div>
</div>
<script>
function $(id) {
    return document.getElementById(id);
}
  //事件冒泡-->阻止事件冒泡,
  //如何阻止事件冒泡: window.event.cancelBubble=true; IE特有的,谷歌支持,火狐不支持
//.preventDefault()    //取消時間默認(rèn)行為。
  // .stopPropagation(); 谷歌和火狐支持。   //描述:取消事件進(jìn)一步捕獲或冒泡

  $("dv1").onclick=function () {
    console.log(this.id);
  };
 $("dv2").onclick=function () {
    console.log(this.id);
    //window.event.cancelBubble=true; //阻止事件冒泡 
  };

  //事件處理參數(shù)對象
  $("dv3").onclick=function (e) {  //加參數(shù)e
    console.log(this.id);   
   e.stopPropagation();  //阻止事件冒泡   //參數(shù)e
    console.log();
  };
</script>
</body>
</html>
從里到外
  • 事件冒泡:多個元素嵌套,有層次關(guān)系,這些元素都注冊了相同的事件,如果里面的元素的事件觸發(fā)了,外面的元素的該事件自動的觸發(fā)了.
    整個事件就是從里到外
捕獲階段
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>title</title>
  <style>
    #dv1 {
      width: 300px;
      height: 200px;
      border: 1px solid ;
    }
    #dv2 {
      width: 250px;
      height: 150px;
      border: 1px solid ;
    }
    #dv3 {
      width: 200px;
      height: 100px;
      border: 1px solid ;
    }
  </style>
</head>
<body>
<div id="dv1">a
  <div id="dv2">b
    <div id="dv3">c</div>
  </div>
</div>
<script>
function btn$(id) {
    return document.getElementById(id);
}
  //捕獲階段:是從里向外

  //同時注冊點擊事件
  var objs = [btn$("dv3"),btn$("dv2"), btn$("dv1")];
  //遍歷注冊事件
  objs.forEach(function (ele) {
    //為每個元素綁定事件
    ele.addEventListener("click", function () {
      console.log(this.id);
    }, true);//捕獲階段是true,冒泡階段是false
  });
  //該屬性在事件參數(shù)對象中存在
</script>
</body>
</html>
從里向外
事件有三個階段:
 * (Dom2傳播機(jī)制)三個階段:
 * 1.事件捕獲階段  :從外向內(nèi)
 * 2.事件目標(biāo)階段  :最開始選擇的那個
 * 3.事件冒泡階段  : 從里向外
 *
 * 為元素綁定事件:
 * addEventListener("沒有on的事件類型",事件處理函數(shù),控制事件階段的)
 * 事件觸發(fā)的過程中,可能會出現(xiàn)事件冒泡的效果,為了阻止事件冒泡--->
 * window.event.cancelBubble=true;谷歌,IE8支持,火狐不支持
 * window.event就是一個對象,是IE中的標(biāo)準(zhǔn)
 * e.stopPropagation();阻止事件冒泡---->谷歌和火狐支持
 * window.event和e都是事件參數(shù)對象,一個是IE的標(biāo)準(zhǔn),一個是火狐的標(biāo)準(zhǔn)
 * 事件參數(shù)e在IE8的瀏覽器中是不存在,此時用window.event來代替
 * addEventListener中第三個參數(shù)是控制事件階段的
 * 事件的階段有三個:
 * 通過e.eventPhase這個屬性可以知道當(dāng)前的事件是什么階段的
 * 如果這個屬性的值是:
 * 1---->捕獲階段
 * 2---->目標(biāo)階段
 * 3---->冒泡
 * 一般默認(rèn)都是冒泡階段,很少用捕獲階段
 * 冒泡階段:從里向外
 * 捕獲階段:從外向內(nèi)

區(qū)別:
onlick與addEventListener的區(qū)別?
1.onclick事件在同一時間只能指向唯一對象
2.addEventListener給一個事件注冊多個listener
3.addEventListener對任何DOM都是有效的,而onclick僅限于HTML
4.addEventListener可以控制listener的觸發(fā)階段,(捕獲/冒泡)。對于多個相同的事件處理器,不會重復(fù)觸發(fā),不需要手動使用removeEventListener清除
5.IE9使用attachEvent和detachEvent

attachEvent與addEventListener的區(qū)別
參數(shù)個數(shù)不相同:

  • addEventListener有三個參數(shù),attachEvent只有兩個,attachEvent添加的事件處理程序只能發(fā)生在冒泡階段,addEventListener第三個參數(shù)可以決定添加的事件處理程序是在捕獲階段還是冒泡階段處理(默認(rèn)冒泡)

  • 第一個參數(shù)意義不同:
    addEventListener第一個參數(shù)是事件類型(比如click,load),而attachEvent第一個參數(shù)指明的是事件處理函數(shù)名稱(onclick,onload)

  • 事件處理程序的作用域不相同:
    addEventListener的作用域是元素本身,this是指的觸發(fā)元素;而attachEvent事件處理程序會在全局變量內(nèi)運行,this是window,所以剛才例子才會返回undefined,而不是元素id

  • 為一個事件添加多個事件處理程序時執(zhí)行順序不同:
    addEventListener添加會按照添加順序執(zhí)行,而attachEvent添加多個事件處理程序時順序無規(guī)律(添加的方法少的時候大多是按添加順序的反順序執(zhí)行的,但是添加的多了就無規(guī)律了),所以添加多個的時候,不依賴執(zhí)行順序的還好,若是依賴于函數(shù)執(zhí)行順序,最好自己處理,不要指望瀏覽器。

自定義事件

var EventCenter = {
  on: function(type, handler){
    document.addEventListener(type, handler)
  },
  fire: function(type, data){
    return document.dispatchEvent(new CustomEvent(type, {
      detail: data
    }))
  }
}

EventCenter.on('hello', function(e){
  console.log(e.detail)
})

EventCenter.fire('hello', '你好')
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • dom對象的innerText和innerHTML有什么區(qū)別? innerHTML指的是從對象的起始位置到終止位置...
    coolheadedY閱讀 577評論 0 0
  • 事件流 JavaScript與HTML之間的交互是通過事件實現(xiàn)的。事件,就是文檔或瀏覽器窗口中發(fā)生的一些特定的交互...
    DHFE閱讀 910評論 0 3
  • 一、問答 1. dom對象的innerText和innerHTML有什么區(qū)別? innerHTML: 也就是從對象...
    饑人谷_羅偉恩閱讀 695評論 0 2
  • 問答 一、dom對象的innerText和innerHTML有什么區(qū)別? innerTextinnerText是一...
    婷樓沐熙閱讀 469評論 0 0
  • 題目1: DOM0 事件和DOM2級在事件監(jiān)聽使用方式上有什么區(qū)別? Dom0級Dom0級事件處理程序是將一個函數(shù)...
    QQQQQCY閱讀 390評論 0 0

友情鏈接更多精彩內(nèi)容