進(jìn)階9 事件

1: DOM0 事件和DOM2級(jí)在事件監(jiān)聽使用方式上有什么區(qū)別?

  • DOM0級(jí)事件處理方式:

    通過javascript制定事件處理程序的傳統(tǒng)方式。就是將一個(gè)函數(shù)賦值給一個(gè)事件處理屬性。至今所有瀏覽器都支持。優(yōu)點(diǎn),簡單且具有跨瀏覽器的優(yōu)勢。
    例:var btn = document.getElementById("btn");
    btn.onclick = function(){
    alert(this.id);//this指定當(dāng)前元素btn
    }
    刪除DOM0事件處理程序,只要將對(duì)應(yīng)事件屬性置為null即可。
    btn.onclick = null;
    缺點(diǎn):一個(gè)事件處理程序只能對(duì)應(yīng)一個(gè)處理函數(shù)。

  • DOM2級(jí)事件處理方式

    DOM2級(jí)事件處理方式指定了,添加事件處理程序和刪除事件處理程序的方法。分別是:
    addEventListener(eventName,func,isPuhuo);
    removeEventListener(eventName,func,isPuhuo);
    參數(shù)分別是,事件處理屬性名稱,處理函數(shù),是否在捕獲時(shí)執(zhí)行事件處理函數(shù)。

    IE中的DOM2級(jí)事件處理使用了attachEvent和detachEvent來實(shí)現(xiàn)。這倆個(gè)方法接受倆個(gè)相同的參數(shù),事件處理名稱和事件處理函數(shù)。IE8以及更早版本只支持冒泡型事件,所以attachEvent添加的事件都會(huì)被添加到冒泡階段。
    例如:
    var btn = document.getElementById("btn");
    btn.attachEvent("onclick",function(){
    alert(this);//此處this是window
    });
    參考:DOM0,DOM2,DOM3事件處理方式區(qū)別

2: attachEvent與addEventListener的區(qū)別?

  • a. 參數(shù)個(gè)數(shù)不相同

這個(gè)最直觀,addEventListener有三個(gè)參數(shù),attachEvent只有兩個(gè),attachEvent添加的事件處理程序只能發(fā)生在冒泡階段,addEventListener第三個(gè)參數(shù)可以決定添加的事件處理程序是在捕獲階段還是冒泡階段處理(我們一般為了瀏覽器兼容性都設(shè)置為冒泡階段)

  • b. 第一個(gè)參數(shù)意義不同

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

  • c. 事件處理程序的作用域不相同

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

  • d. 為一個(gè)事件添加多個(gè)事件處理程序時(shí),執(zhí)行順序不同

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

3: 解釋IE事件冒泡和DOM2事件傳播機(jī)制?

IE的事件冒泡:事件開始時(shí)由最具體的元素接收,然后逐級(jí)向上傳播到較為不具體的元素
DOM事件流:DOM2級(jí)事件規(guī)定事件流包括三個(gè)階段,事件捕獲階段,處于目標(biāo)階段,事件冒泡階段,首先發(fā)生的是事件捕獲,為截取事件提供機(jī)會(huì),然后是實(shí)際目標(biāo)接收事件,最后是冒泡階段

IE點(diǎn)擊div區(qū)域
DOM2中點(diǎn)擊div區(qū)域

4:如何阻止事件冒泡? 如何阻止默認(rèn)事件?

事件對(duì)象根據(jù)不同類型有不同的屬性和方法,但是所有事件都會(huì)包含,阻止事件冒泡(或者捕獲),以及阻止默認(rèn)事件的方法,但是在DOM和IE中具有一些不同點(diǎn)。

在DOM中:

  • stopPropagation()方法可以停止事件在DOM層次的傳播,即取消進(jìn)一步的事件捕獲或冒泡。
  • 要阻止事件的默認(rèn)行為,可以使用preventDefault()方法,前提是cancelable值為true,比如我們可以阻止鏈接導(dǎo)航這一默認(rèn)行為:
document.querySelector('#btn').onclick = function (e) {
    e.preventDefault();
}

在IE中:

cancelBubble 默認(rèn)為false,設(shè)置為true后可以取消事件冒泡
returnValue 默認(rèn)為true,設(shè)為false可以取消事件默認(rèn)行為

5:有如下代碼,要求當(dāng)點(diǎn)擊每一個(gè)元素li時(shí)控制臺(tái)展示該元素的文本內(nèi)容(不考慮兼容)

<ul class="ct">
    <li>這里是</li>
    <li>曉風(fēng)殘?jiān)?lt;/li>
    <li>JS學(xué)習(xí)大本營</li>
</ul>
<script>
  document.querySelector('.ct').addEventListener('click', function(e){
    if( e.target.tagName.toLowerCase() === 'li'){ //增加判斷,確定點(diǎn)在了li上
      console.log(e.target.innerText)
    }
  }) 
</script>

預(yù)覽地址

6: 補(bǔ)全代碼,要求:

  • 需求1:當(dāng)點(diǎn)擊按鈕開頭添加時(shí)在<li>這里是</li>元素前添加一個(gè)新元素,內(nèi)容為用戶輸入的非空字符串;當(dāng)點(diǎn)擊結(jié)尾添加時(shí)在最后一個(gè) li 元素后添加用戶輸入的非空字符串.
  • 需求2:當(dāng)點(diǎn)擊每一個(gè)元素li時(shí)控制臺(tái)展示該元素的文本內(nèi)容。
<ul class="ct">
    <li>這里是</li>
    <li>曉風(fēng)殘?jiān)?lt;/li>
    <li>大前端</li>
</ul>
<input class="ipt-add-content" placeholder="添加內(nèi)容"/>
<button id="btn-add-start">開頭添加</button>
<button id="btn-add-end">結(jié)尾添加</button>
<script>
//你的代碼
</script>

我的思路:1. 創(chuàng)建新元素li 2. 給li里添加非空內(nèi)容 3. 把新li添加到ul內(nèi)指定位置
首先貼出公共部分,同時(shí)也是需求1,和下面的代碼合在一起,完成我們的目的:

    //  實(shí)現(xiàn) 當(dāng)點(diǎn)擊每一個(gè)元素li時(shí)控制臺(tái)展示該元素的文本內(nèi)容
    $('.ct').addEventListener('click', function(e){
      var target = e.target
      if(target.tagName.toLowerCase() === 'li'){
        console.log(target.innerText)
      }
    })

    // 定義$選擇器
    function $(single){
      return document.querySelector(single)
    }

需求2
第一種:

    //分別綁定兩個(gè)按鈕
    $('#btn-add-start').addEventListener('click', function(){
      var newLi = document.createElement('li')
      var ipt = $('.ipt-add-content')
      var ct = $('.ct')
      if(/\S/.test(ipt.value) && ipt.value !== ''){
        newLi.innerText = ipt.value
        ct.insertBefore(newLi, ct.firstChild)
      }else{
        alert('好歹輸入點(diǎn)什么')
      }
    })
    $('#btn-add-end').addEventListener('click', function(){
      var newLi = document.createElement('li')
      var ipt = $('.ipt-add-content')
      var ct = $('.ct')
      if(/\S/.test(ipt.value) && ipt.value !== ''){
        newLi.innerText = ipt.value
        ct.appendChild(newLi)
      }else{
        alert('好歹輸入點(diǎn)什么')
      }
    })

但是這樣代碼復(fù)用性太低,所以下面使用了事件代理,給兩個(gè)按鈕安排了個(gè)爸爸

第二種:

    $('.btn').addEventListener('click', function(e){
      var newLi = document.createElement('li')
      var ipt = $('.ipt-add-content')
      var ct = $('.ct')
      var target = e.target
      if(/\S/.test(ipt.value) && ipt.value !== ''){
        newLi.innerText = ipt.value
        if(target.id === 'btn-add-start'){
          ct.insertBefore(newLi, ct.firstChild)
        }else if(target.id === 'btn-add-end'){
          ct.appendChild(newLi)
        }
      }
    })

因?yàn)檫@里是綁定的button的爸爸,所以在整個(gè)爸爸范圍內(nèi),如果是空的,點(diǎn)擊都會(huì)出現(xiàn)彈窗,所以這里就不添加alert了,除非把id判斷放在外層,然后里面分別再次判斷是否非空,如下面所示:

    $('.btn').addEventListener('click', function(e){
      var newLi = document.createElement('li')
      var ipt = $('.ipt-add-content')
      var ct = $('.ct')
      var target = e.target
      if(target.id === 'btn-add-start'){
        if(/\S/.test(ipt.value) && ipt.value !== ''){
          newLi.innerText = ipt.value
          ct.insertBefore(newLi, ct.firstChild)
        }else{alert('好歹輸入點(diǎn)什么')}
      }else if(target.id === 'btn-add-end'){
        if(/\S/.test(ipt.value) && ipt.value !== ''){
          newLi.innerText = ipt.value
          ct.appendChild(newLi)
        }else{alert('好歹輸入點(diǎn)什么')}
      }
    })

預(yù)覽地址

7: 補(bǔ)全代碼,要求:當(dāng)鼠標(biāo)放置在li元素上,會(huì)在img-preview里展示當(dāng)前l(fā)i元素的data-img對(duì)應(yīng)的圖片。

<ul class="ct">
   <li data-img="1.png">鼠標(biāo)放置查看圖片1</li>
   <li data-img="2.png">鼠標(biāo)放置查看圖片2</li>
   <li data-img="3.png">鼠標(biāo)放置查看圖片3</li>
</ul>
<div class="img-preview"></div>
<script>
//你的代碼
</script>

思路如下:
stepA:1. ul綁定mouseover事件 2. 創(chuàng)建img子元素,從li里獲取src屬性 3. 把img添加到div里
stepB:2. target綁定mouseout事件 2. 使用removeChild()方法刪除子元素img

$('.ct').addEventListener('mouseover', function(e){
  var target = e.target
  if(target.tagName.toLowerCase() === 'li'){
    var img = document.createElement('img')
    img.setAttribute('src', target.getAttribute('data-img'))
    $('.img-preview').appendChild(img)
  }
  target.addEventListener('mouseout', function(){
    $('.img-preview').removeChild(img)
  })
})

function $(single){
  return document.querySelector(single)
}

預(yù)覽地址

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

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

  • 1.DOM0 事件和DOM2級(jí)在事件監(jiān)聽使用方式上有什么區(qū)別? DOM0級(jí)事件在DOM0級(jí)事件處理程序,事件名以'...
    24_Magic閱讀 314評(píng)論 0 0
  • 1. DOM0事件和DOM2級(jí)在事件監(jiān)聽使用方式上有什么區(qū)別? 添加方式:DOM0級(jí)事件是通過內(nèi)聯(lián)方式 ,或是...
    饑人谷_哈嚕嚕閱讀 211評(píng)論 0 0
  • 題目1: DOM0 事件和DOM2級(jí)在事件監(jiān)聽使用方式上有什么區(qū)別? -DOM0事件監(jiān)聽及使用的本質(zhì)是將事件處理程...
    cheneyzhangch閱讀 302評(píng)論 0 0
  • 品名:Clorts洛弛溯溪涼鞋WT-24 價(jià)值:549元 購買:Clorts戶外旗艦店 ◆ 產(chǎn)品介紹 ◆ 因?yàn)镃l...
    益動(dòng)小編就是我閱讀 430評(píng)論 1 1
  • 有好幾種安裝插件,gizmos, python腳本的方法。 最簡單的就是用home目錄的 ~/.nuke目錄,其在...
    N景波閱讀 4,019評(píng)論 0 1

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