成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

javascript事件基礎(chǔ)知識(shí)

ad6623 / 2373人閱讀

摘要:可選,布爾值,指定事件是否在捕獲或冒泡階段執(zhí)行,默認(rèn)冒泡。適用范圍參數(shù)介紹必須,字符串,事件名稱。必須,指定事件觸發(fā)時(shí)執(zhí)行的函數(shù)。事件冒泡事件冒泡與事件捕獲恰恰相反,事件冒泡順序是由內(nèi)到外進(jìn)行事件傳播,直到根節(jié)點(diǎn)。

什么是事件

javascript與HTML之間交互就是通過(guò)事件實(shí)現(xiàn)的,事件就是文檔或?yàn)g覽器窗口中發(fā)生的一些特定的交互瞬間。事件在瀏覽器中是以對(duì)象的形式存在的,即event,觸發(fā)一個(gè)事件,就會(huì)產(chǎn)生一個(gè)事件對(duì)象event,該對(duì)象包含著所有與事件有關(guān)的信息,包括導(dǎo)致事件的元素、事件的類型以及其他與特定事件相關(guān)的信息。

DOM元素添加事件 1.DOM元素事件屬性
2.javascript腳本添加事件

a. element.onclick=function(e){}
b. element.addEventListener(event,function(e),useCapture)

適用范圍:現(xiàn)代瀏覽器(IE9+, Firefox , chorme, safari, opera)

參數(shù)介紹:event必須,事件名稱。(注:不含“on”,比如“click”、“mouseover”等)。function必須,指定事件觸發(fā)時(shí)執(zhí)行的函數(shù)。useCapture可選,布爾值,指定事件是否在捕獲或冒泡階段執(zhí)行,默認(rèn)false(冒泡)。

c. element.attachEvent(event,function(e))

適用范圍:IE 6、7、8

參數(shù)介紹:event 必須,字符串,事件名稱。(注:含“on”,比如“onclick”、“onmouseover”等)。function必須,指定事件觸發(fā)時(shí)執(zhí)行的函數(shù)。


擴(kuò)展:原生Javascript寫(xiě)法,跨瀏覽器添加事件

 var EventUtil = {
     // 添加事件監(jiān)聽(tīng)
      add: function(element, type, callback){
          if(element.addEventListener){
             element.addEventListener(type, callback, false);
          } else if(element.attachEvent){
              element.attachEvent("on" + type, callback);
         } else {
             element["on" + type] = callback;
         }
     }
     // 移除事件監(jiān)聽(tīng)
    remove: function(element, type, callback){
         if(element.removeEventListener){
             element.removeEventListener(type, callback, false);
         } else if(element.detachEvent){
             element.detachEvent("on" + type, callback);
         } else {
             element["on" + type] = null;
         }
     }
 }
 
 

事件冒泡

事件冒泡(dubbed bubbling):與事件捕獲恰恰相反,事件冒泡順序是由內(nèi)到外進(jìn)行事件傳播,直到根節(jié)點(diǎn)。

注:無(wú)論是事件捕獲還是事件冒泡,它們都有一個(gè)共同的行為,就是事件傳播

阻止事件捕獲/事件冒泡
 event.stopPropagation()   
 event.stopImmediatePropagation()

event.stopPropagation()
會(huì)阻止事件繼續(xù)分發(fā)到其他document節(jié)點(diǎn),但是當(dāng)前節(jié)點(diǎn)綁定的多個(gè)事件會(huì)繼續(xù)按注冊(cè)的順序執(zhí)行

event.stopImmediatePropagation()
不僅阻止事件繼續(xù)分發(fā)到其他document,還會(huì)將事件分發(fā)就地停止,在當(dāng)前事件之后注冊(cè)的其他事件,都不會(huì)執(zhí)行

舉個(gè)栗子:此栗子是阻止事件捕獲,阻止事件冒泡原理一樣

//執(zhí)行結(jié)果 alert("div1第一次執(zhí)行"); alert("div1第二次執(zhí)行");
//執(zhí)行結(jié)果 alert("div1第一次執(zhí)行");
事件代理 什么是事件代理

事件代理也可以稱之為事件委托,事件代理就是在祖先級(jí)DOM元素綁定一個(gè)事件,當(dāng)觸發(fā)子孫級(jí)DOM元素的事件時(shí),利用事件冒泡的原理來(lái)觸發(fā)綁定在祖先級(jí)DOM的事件。

那這是什么意思呢?網(wǎng)上的各位大牛們講事件代理基本上都用了同一個(gè)例子,就是取快遞來(lái)解釋這個(gè)現(xiàn)象,借花獻(xiàn)佛,大家認(rèn)真領(lǐng)會(huì)一下事件代理到底是一個(gè)什么原理:
有三個(gè)同事預(yù)計(jì)會(huì)在周一收到快遞。為簽收快遞,有兩種辦法:一是三個(gè)人在公司門(mén)口等快遞;二是委托給前臺(tái)MM代為簽收?,F(xiàn)實(shí)當(dāng)中,我們大都采用委托的方案。前臺(tái)MM收到快遞后,她會(huì)判斷收件人是誰(shuí),然后按照收件人的要求簽收,甚至代為付款。這種方案還有一個(gè)優(yōu)勢(shì),那就是即使公司里來(lái)了新員工,前臺(tái)MM也會(huì)在收到寄給新員工的快遞后核實(shí)并代為簽收。

這里其實(shí)有2層意思的:
第一,現(xiàn)在委托前臺(tái)的同事是可以代為簽收的,即程序中的現(xiàn)有的dom節(jié)點(diǎn)是有事件的;
第二,新員工也是可以被前臺(tái)MM代為簽收的,即程序中新添加的dom節(jié)點(diǎn)也是有事件的。

為什么要用事件代理

一般來(lái)說(shuō),dom需要有事件處理程序,我們都會(huì)直接給它設(shè)事件處理程序就好了,那如果是很多的dom需要添加事件處理呢?比如我們有100個(gè)li,每個(gè)li都有相同的click點(diǎn)擊事件,可能我們會(huì)用for循環(huán)的方法,來(lái)遍歷所有的li,然后給它們添加事件,那這么做會(huì)存在什么影響呢?

在JavaScript中,添加到頁(yè)面上的事件處理程序數(shù)量將直接關(guān)系到頁(yè)面的整體運(yùn)行性能,因?yàn)樾枰粩嗟呐cdom節(jié)點(diǎn)進(jìn)行交互,訪問(wèn)dom的次數(shù)越多,引起瀏覽器重繪與重排的次數(shù)也就越多,就會(huì)延長(zhǎng)整個(gè)頁(yè)面的交互就緒時(shí)間,這就是為什么性能優(yōu)化的主要思想之一就是減少DOM操作的原因;如果要用事件代理,就會(huì)將所有的操作放到j(luò)s程序里面,與dom的操作就只需要交互一次,這樣就能大大的減少與dom的交互次數(shù),提高性能;

每個(gè)函數(shù)都是一個(gè)對(duì)象,是對(duì)象就會(huì)占用內(nèi)存,對(duì)象越多,內(nèi)存占用率就越大,自然性能就越差了(內(nèi)存不夠用,是硬傷),比如上面的100個(gè)li,就要占用100個(gè)內(nèi)存空間,如果是1000個(gè),10000個(gè)呢,那只能呵呵了,如果用事件代理,那么我們就可以只對(duì)它的父級(jí)(如果只有一個(gè)父級(jí))這一個(gè)對(duì)象進(jìn)行操作,這樣我們就需要一個(gè)內(nèi)存空間就夠了,是不是省了很多,自然性能就會(huì)更好。

事件代理的實(shí)現(xiàn)

在介紹事件代理的方法之前,先來(lái)看一段一般方法的栗子:

  • 111
  • 222
  • 333
  • 444

上面的代碼很簡(jiǎn)單,我們看看有多少次的dom操作,首先要找到ul,然后遍歷li,然后點(diǎn)擊li的時(shí)候,又要找一次目標(biāo)的li的位置,才能執(zhí)行最后的操作,每次點(diǎn)擊都要找一次li。

用事件代理的方式來(lái)實(shí)現(xiàn),上栗子:

window.onload = function(){
    var ulDelegate= document.getElementById("ulDelegate");
    ulDelegate.onclick = function(){
         alert("Delegate");
    }
}

這里用父級(jí)ul做事件處理,當(dāng)li被點(diǎn)擊時(shí),由于冒泡原理,事件就會(huì)冒泡到ul上,因?yàn)閡l上有點(diǎn)擊事件,所以事件就會(huì)觸發(fā),當(dāng)然,這里當(dāng)點(diǎn)擊ul的時(shí)候,也是會(huì)觸發(fā)的。

那么問(wèn)題就來(lái)了,如果我想讓事件代理的效果跟直接給節(jié)點(diǎn)的事件效果一樣怎么辦,比如說(shuō)只有點(diǎn)擊li才會(huì)觸發(fā),這時(shí),Event對(duì)象就派上用場(chǎng)了,Event提供了一個(gè)屬性叫target,可以返回事件的目標(biāo)節(jié)點(diǎn),我們稱為事件源,也就是說(shuō),target就可以表示為當(dāng)前的事件操作的dom,但是不是真正操作dom,這個(gè)是有兼容性的,標(biāo)準(zhǔn)瀏覽器用ev.target,IE瀏覽器用event.srcElement,此時(shí)只是獲取了當(dāng)前節(jié)點(diǎn)的位置,并不知道是什么節(jié)點(diǎn)名稱,這里我們用nodeName來(lái)獲取具體是什么標(biāo)簽名,這個(gè)返回的是一個(gè)大寫(xiě)的,我們可以轉(zhuǎn)成小寫(xiě)再做比較,或者不轉(zhuǎn)。

window.onload = function(){
  var ulDelegate= document.getElementById("ulDelegate");
  ulDelegate.onclick = function(ev){
    var ev = ev || window.event;
    var target = ev.target || ev.srcElement;
    if(target.nodeName.toLowerCase() == "li"){
       alert("Delegate");
      alert(target.innerHTML);
    }
  }
}

這樣就只有點(diǎn)擊li會(huì)觸發(fā)事件了,且每次只執(zhí)行一次dom操作,如果li數(shù)量很多的話,將大大減少dom的操作,優(yōu)化的性能可想而知!

上面的栗子是說(shuō)li操作的是同樣的效果,如果每個(gè)li被點(diǎn)擊的效果都不一樣,上栗子:

  • 添加
  • 刪除
  • 修改

再來(lái)最后一個(gè)事件代理的栗子,當(dāng)我們新增一個(gè)li元素的時(shí)候,同樣先看一下一般寫(xiě)法:

  • 111
  • 222
  • 333
  • 444

再來(lái)看一下事件代理的寫(xiě)法:

    window.onload = function(){
        var ulDelegate = document.getElementById("ulDelegate");
        var addLi = document.getElementById("addLi");
        
        ulDelegate.onclick = function(ev){
            var ev = ev || window.event;
            var target = ev.target || ev.srcElement;
            if(target.nodeName.toLowerCase() == "li"){
                alert("Delegate");
                alert(target.innerHTML);
            }
        };

        addLi.onclick = function(){
            var addLiElement = document.createElement("li");
            addLiElement .innerHTML = 10000*Math.random();
            ulDelegate.appendChild(addLiElement );
        }

    }

看,上面是用事件單例的方式,新添加的子元素是帶有事件效果的,我們不需要去遍歷元素的子節(jié)點(diǎn),只需要給父級(jí)元素添加事件就好了,其他的都是在js里面的執(zhí)行,這樣可以大大的減少dom操作,這才是事件代理的精髓所在。

總結(jié)

事件是將javascript與網(wǎng)頁(yè)聯(lián)系在一起的主要方式,在使用事件時(shí),需要考慮如下一些內(nèi)存與性能方面的問(wèn)題。

有必要限制夜歌頁(yè)面中事件處理程序的數(shù)量,數(shù)量太多會(huì)導(dǎo)致占用大量?jī)?nèi)存,而且也會(huì)讓用戶頁(yè)面反應(yīng)不夠靈敏

建立在事件冒泡機(jī)制之上的時(shí)間委托技術(shù),可以有效的減少時(shí)間處理程序的數(shù)量

建議在瀏覽器卸載頁(yè)面之前移除頁(yè)面中的所有事件處理程序

事件是javascript中最重要的主題之一,深入理解事件的工作機(jī)制以及它們對(duì)性能的影響是至關(guān)重要的

(總結(jié)摘自javascript高級(jí)程序設(shè)計(jì)第三版)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/109153.html

相關(guān)文章

  • 總結(jié)javascript基礎(chǔ)概念(二):事件隊(duì)列循環(huán)

    摘要:而事件循環(huán)是主線程中執(zhí)行棧里的代碼執(zhí)行完畢之后,才開(kāi)始執(zhí)行的。由此產(chǎn)生的異步事件執(zhí)行會(huì)作為任務(wù)隊(duì)列掛在當(dāng)前循環(huán)的末尾執(zhí)行。在下,觀察者基于監(jiān)聽(tīng)事件的完成情況在下基于多線程創(chuàng)建。 主要問(wèn)題: 1、JS引擎是單線程,如何完成事件循環(huán)的? 2、定時(shí)器函數(shù)為什么計(jì)時(shí)不準(zhǔn)確? 3、回調(diào)與異步,有什么聯(lián)系和不同? 4、ES6的事件循環(huán)有什么變化?Node中呢? 5、異步控制有什么難點(diǎn)?有什么解決方...

    zhkai 評(píng)論0 收藏0
  • 聊聊DOM中很重要的一個(gè)知識(shí)點(diǎn):事件

    摘要:事件事件就是瀏覽器告知程序,用戶的行為,用戶點(diǎn)擊了頁(yè)面中的某個(gè)按鈕或者用戶輸入用戶名或密碼等操作可以稱為事件事件的類型事件根據(jù)使用的場(chǎng)景不同,可以分為如下幾種依賴于設(shè)備的輸入事件鍵盤(pán)事件和鼠標(biāo)事件,這些事件都是直接和設(shè)備相關(guān)的獨(dú)立于設(shè)備的輸 事件 事件就是瀏覽器告知JavaScript程序,用戶的行為,用戶點(diǎn)擊了HTML頁(yè)面中的某個(gè)按鈕或者用戶輸入用戶名或密碼等操作可以稱為事件 事件的...

    church 評(píng)論0 收藏0
  • 【連載】前端個(gè)人文章整理-從基礎(chǔ)到入門(mén)

    摘要:個(gè)人前端文章整理從最開(kāi)始萌生寫(xiě)文章的想法,到著手開(kāi)始寫(xiě),再到現(xiàn)在已經(jīng)一年的時(shí)間了,由于工作比較忙,更新緩慢,后面還是會(huì)繼更新,現(xiàn)將已經(jīng)寫(xiě)好的文章整理一個(gè)目錄,方便更多的小伙伴去學(xué)習(xí)。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個(gè)人前端文章整理 從最開(kāi)始萌生寫(xiě)文章的想法,到著手...

    madthumb 評(píng)論0 收藏0
  • #yyds干貨盤(pán)點(diǎn)# 前端基礎(chǔ)知識(shí)面試集錦3

    摘要:當(dāng)解釋器尋找引用值時(shí),會(huì)首先檢索其在棧中的地址,取得地址后從堆中獲得實(shí)體如何實(shí)現(xiàn)繼承構(gòu)造繼承原型繼承實(shí)例繼承拷貝繼承原型機(jī)制或和方法去實(shí)現(xiàn)較簡(jiǎn)單,建議使用構(gòu)造函數(shù)與原型混合方式。它是基于的一個(gè)子集。 JavaScript介紹js的基本數(shù)據(jù)類型。Undefined、Null、Boolean、Number、Stri...

    番茄西紅柿 評(píng)論0 收藏2637

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<