乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      聊聊事件冒泡與事件捕獲

       印度阿三17 2019-04-05

      什么是事件?

      ?  事件是文檔和瀏覽器窗口中發(fā)生的特定的交互瞬間。

      什么是事件流:

      ? ?事件流描述的是從頁(yè)面中接受事件的順序( 說(shuō)白了就是解決頁(yè)面中事件流發(fā)生順序的問(wèn)題。),但有意思的是,微軟(IE)和網(wǎng)景(Netscape)開(kāi)發(fā)團(tuán)隊(duì)居然提出了兩個(gè)截然相反的事件流概念,IE的事件流是事件冒泡流(event bubbling),而Netscape的事件流是事件捕獲流(event capturing)。

      ?

      讓我們先聊聊DOM0級(jí)事件與DOM2級(jí)事件

      ?

      • DOM0

      直接通過(guò) onclick寫(xiě)在html里面的事件, 比如:

      在標(biāo)簽內(nèi)寫(xiě)onclick事件

      <input onclick="alert(1)" />

      ?在JS寫(xiě)onlicke=function(){}函數(shù)

      1 document.getElementById("myButton").onclick = function () {
      2     alert('thanks');
      3 }

      ?

      ?

      • DOM2

      主流瀏覽器DOM2級(jí)事件是通過(guò)以下兩個(gè)方法用于處理指定和刪除事件處理程序的操作:

      1. 添加事件 ??addEvenetListener ? ?------ ? 可以為元素添加多個(gè)事件處理程序,觸發(fā)時(shí)會(huì)按照添加順序依次調(diào)用。
      2. 刪除事件 ??removeEventListener ? ------- ??不能移除匿名添加的函數(shù)。

      它們都有三個(gè)參數(shù):

      1. 第一個(gè)參數(shù)是事件名(如click)。
      2. 第二個(gè)參數(shù)是事件處理程序函數(shù)。 ?可以為匿名函數(shù),也可以為命名函數(shù)(但如果需要?jiǎng)h除事件,必須是命名函數(shù))
      3. 第三個(gè)參數(shù)如果是true則表示在捕獲階段調(diào)用,為false表示在冒泡階段調(diào)用。

      使用DOM 2級(jí)事件處理程序的主要好處是可以添加多個(gè)事件處理程序,事件處理會(huì)按照他們的順序觸發(fā),通過(guò)addEventListener添加的事件只能用removeEventListener來(lái)移除,移除時(shí)傳入的參數(shù)與添加時(shí)使用的參數(shù)必須相同,這也意味著添加的匿名函數(shù)將無(wú)法移除,(注意:我們默認(rèn)的第三個(gè)參數(shù)都是默認(rèn)false,是指在冒泡階段添加,大多數(shù)情況下,都是將事件處理程序添加到事件的冒泡階段,這樣可以最大限度的兼容各個(gè)瀏覽器

      ?

      匿名函數(shù)

      1 //這是一個(gè)DOM 2級(jí)事件 添加事件最簡(jiǎn)單的方式(此時(shí)添加的是一個(gè)匿名函數(shù))
      2     <button>按鈕</button>
      3     <script>
      4         var btn=document.querySelector('button');
      5         btn.addEventListener('click',function(){
      6             console.log('我是按鈕')
      7         },false)   //當(dāng)?shù)谌齻€(gè)參數(shù)不寫(xiě)時(shí),也是默認(rèn)為false(冒泡時(shí)添加事件)
      8     </script>

      ?

      命名函數(shù)

      1     <button>按鈕</button>
      2     <script>
      3         var btn=document.querySelector('button');
      4         btn.addEventListener('click',foo,false);
      5         function foo(){
      6             console.log('我是按鈕')
      7         }
      8            //其實(shí)操作就是把寫(xiě)在里面的函數(shù)拿到了外面,而在原來(lái)的位置用函數(shù)名來(lái)代替
      9     </script>

      ?


      ?

      看完以上的,我們?cè)倭私馐录芭菖c捕獲

      ?


      ?

      第一種(事件冒泡)IE提出

      IE提出的事件流叫做事件冒泡,即事件開(kāi)始時(shí)由最具體的元素接收,然后逐級(jí)向上傳播到較為不具體的節(jié)點(diǎn)。

       1 <!DOCTYPE html>
       2 <html lang="en">
       3 <head>
       4     <meta charset="UTF-8">
       5     <title>Title</title>
       6 </head>
       7 <body onclick="bodyClick()">
       8 
       9     <div onclick="divClick()">
      10         <button onclick="btn()">
      11             <p onclick="p()">點(diǎn)擊冒泡</p>
      12         </button>
      13     </div>
      14     <script>
      15        
      16        function p(){
      17           console.log('p標(biāo)簽被點(diǎn)擊')
      18        }
      19         function btn(){
      20             console.log("button被點(diǎn)擊")
      21         }
      22          function divClick(event){
      23              console.log('div被點(diǎn)擊');
      24          }
      25         function bodyClick(){
      26             console.log('body被點(diǎn)擊')
      27         }
      28 
      29     </script>
      30 
      31 </body>
      32 </html>

      接下來(lái)我們點(diǎn)擊一下頁(yè)面上的p元素,如下所示

      正如上面我們所說(shuō)的,它會(huì)從一個(gè)最具體的的元素接收,然后逐級(jí)向上傳播, p=>button=>div=>body..........事件冒泡可以形象地比喻為把一顆石頭投入水中,泡泡會(huì)一直從水底冒出水面。

      ??


      ??

      第二種(事件捕獲)網(wǎng)景提出

      事件捕獲流的思想是不太具體的DOM節(jié)點(diǎn)應(yīng)該更早接收到事件,而最具體的節(jié)點(diǎn)應(yīng)該最后接收到事件,針對(duì)上面同樣的例子,點(diǎn)擊按鈕,那么此時(shí)click事件會(huì)按照這樣傳播:(下面我們就借用addEventListener的第三個(gè)參數(shù)來(lái)模擬事件捕獲流)

       1 <!DOCTYPE html>
       2 <html lang="en">
       3 <head>
       4     <meta charset="UTF-8">
       5     <title>Title</title>
       6 </head>
       7 <body>
       8 
       9 <div>
      10     <button>
      11         <p>點(diǎn)擊捕獲</p>
      12     </button>
      13 </div>
      14 <script>
      15     var oP=document.querySelector('p');
      16     var oB=document.querySelector('button');
      17     var oD=document.querySelector('div');
      18     var oBody=document.querySelector('body');
      19 
      20     oP.addEventListener('click',function(){
      21         console.log('p標(biāo)簽被點(diǎn)擊')
      22     },true);
      23 
      24     oB.addEventListener('click',function(){
      25         console.log("button被點(diǎn)擊")
      26     },true);
      27 
      28     oD.addEventListener('click',  function(){
      29         console.log('div被點(diǎn)擊')
      30     },true);
      31 
      32     oBody.addEventListener('click',function(){
      33         console.log('body被點(diǎn)擊')
      34     },true);
      35 
      36 </script>
      37 </body>
      38 </html>

      同樣我們看一下后臺(tái)的打印結(jié)果

      和冒泡流完全相反,從最不具體的元素接收到最具體的元素接收事件? body=>div=>button=>p?

      ?


      ?

      • 事件代理

      在實(shí)際的開(kāi)發(fā)當(dāng)中,利用事件流的特性,我們可以使用一種叫做事件代理的方法。

      <ul id="color-list">
          <li>red</li>
          <li>yellow</li>
          <li>blue</li>
          <li>green</li>
          <li>black</li>
          <li>white</li>
      </ul>

      ?

      ?如果點(diǎn)擊頁(yè)面中的li元素,然后輸出li當(dāng)中的顏色,我們通常會(huì)這樣寫(xiě):

      1 var list_li = document.getElementsByTagName('li');
      2 for (var i = 0; i < list_li.length; i  ) {
      3     list_li[i].addEventListener('click',foo,false);
      4 }
      5 function foo (e) {
      6    let x = e.target;
      7    console.log(x.innerHTML)
      8 }

      ?

      利用事件流的特性,我們只綁定一個(gè)事件處理函數(shù)也可以完成:

      1 var list_ul = document.getElementById('color-list');
      2 list_ul.addEventListener('click', foo, false);
      3 function foo (e) {
      4     let x = e.target;
      5     if (x.nodeName == 'LI') {
      6       console.log(x.innerHTML)
      7     }
      8 }

      ?

      ?


      ?

      • 冒泡還是捕獲?

        對(duì)于事件代理來(lái)說(shuō),在事件捕獲或者事件冒泡階段處理并沒(méi)有明顯的優(yōu)劣之分,但是由于事件冒泡的事件流模型被所有主流的瀏覽器兼容,從兼容性角度來(lái)說(shuō)還是建議大家使用事件冒泡模型。

      ?

        IE瀏覽器兼容

         IE瀏覽器對(duì)addEventListener兼容性并不算太好,只有IE9以上可以使用。

         要兼容舊版本的IE瀏覽器,可以使用IE的attachEvent函數(shù)

      object.attachEvent(event, function)

         兩個(gè)參數(shù)與addEventListener相似,分別是事件和處理函數(shù),默認(rèn)是事件冒泡階段調(diào)用處理函數(shù)。并且由于IE瀏覽器只支持事件冒泡,所以添加的程序都被添加到冒泡階段。要注意的是,寫(xiě)事件名時(shí)候要加上"on"前綴("onload"、"onclick"等)。

      ?

       區(qū)別

        addEventListener與attachEvent除了參數(shù)個(gè)數(shù)以及第一個(gè)參數(shù)意義不同外。還有如下兩點(diǎn):

      1. 事件處理程序的作用域不相同:addEventListener的作用域是元素本身,this指的是觸發(fā)元素。而attachEvent事件處理程序會(huì)在全局變量?jī)?nèi)運(yùn)行,this指的是window,所以剛才的例子返回的結(jié)果是undefined,而不是元素id。
      2. 為一個(gè)事件添加多個(gè)事件處理程序時(shí),執(zhí)行順序不同:使用addEventListener時(shí)瀏覽器會(huì)按照添加順序執(zhí)行,IE瀏覽器使用attachEvent時(shí),如果添加的方法過(guò)多時(shí),IE瀏覽器將不會(huì)按照順序執(zhí)行。

      ?


      ?

      • 阻止事件冒泡與阻止默認(rèn)事件

        阻止事件冒泡 ??stopPropagation() 方法

        可以阻止事件冒泡,也可以阻止事件捕獲,也可以阻止處于目標(biāo)階段

        使用stopPaopagation()方法可以停止事件在DOM層次的傳播,不再派發(fā)事件。

       1 <div id="p">parent
       2       <div id="c">child</div>
       3 </div>
       4 <script type="text/javascript">
       5 var p = document.getElementById('p'),
       6       c = document.getElementById('c');
       7       c.addEventListener('click', function (e) {
       8       e.stopPropagation()
       9            alert('子節(jié)點(diǎn)冒泡')   //不再向上冒泡到父級(jí)
      10 }, false);
      11 p.addEventListener('click', function () {
      12          alert('父節(jié)點(diǎn)冒泡')}, false);
      13 </script>

      ?

        阻止默認(rèn)事件 ??event.preventDefault() 方法 ? (基本沒(méi)作用吧...很少有需求將默認(rèn)事件取消掉吧)

      event.preventDefault()

      ?

      ?

      來(lái)源:http://www./content-4-156851.html

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多