欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Javascript 事件流和事件綁定

 更新時間:2009年07月16日 01:32:37   作者:  
本文中的部分觀點參考至《Javascript高級程序設(shè)計》(很好的一本書,推薦大家看看?。琣ddEvent函數(shù)借鑒了YUI2.7的_addListener方法,這里也要謝謝YUI那些牛人,向他們致敬!

事件流

瀏覽器中的事件流意味著頁面上可有不僅一個,甚至多個元素響應同一個事件。而這一個或多個元素響應事件發(fā)生的先后順序在各個瀏覽器(主要針對IE和Netscape)上是不同的。

冒泡型事件(Dubbed Bubbling)

IE上的解決方案就是冒泡型事件(Dubbed Bubbling)。冒泡型事件的基本思想是,事件按照從最特定的事件目標到最不特定的事件目標(document對象)的順序觸發(fā)。

示例(1):點擊我觸發(fā)冒泡型事件流

示例(1)的XHTML代碼結(jié)構(gòu):

<span id="cnt0">
     <a href=”#1″ id=”link0″>點擊我觸發(fā)冒泡型事件流</a>
</span>

這個示例里我同時給span和a標簽綁定了click事件,大家看到了,我們點擊這個a標簽,一次點擊(click)同時觸發(fā)了兩個元素a和span的事件。先觸發(fā)的是綁定給a標簽的click事件,然后觸發(fā)的是span標簽的click事件。也就是前面提到的“頁面上可有不僅一個,甚至多個元素響應同一個事件”和“事件按照從最特定的事件目標到最不特定的事件目標(document對象)的順序觸發(fā)”。

這個示例里我們點擊的第一目標是a標簽這個鏈接,它就是前面提到的“最特定的事件目標”,然后才是span這個相對“不特定的事件目標”。再看看我的XHTML代碼結(jié)構(gòu),你會發(fā)現(xiàn)a標簽包含在span標簽中,也就是說span是a標簽的父節(jié)點,如果大家還不是很清晰的知道他們之間的關(guān)系,讓我們看看下面的這個DOM樹的結(jié)構(gòu)圖:

示例(1)

事件觸發(fā)的順序是從最特定的目標,沿著DOM樹不斷的向上觸發(fā)click事件,就像氣泡從下一直上冒的過程一樣。“冒泡型”也就是這么得來的,也很形象。這里要說明的是,由于我只給a和span綁定了click事件,所以“冒”到span就到頂了,如果你也給包含他們的p標簽還有document綁定click事件,這個冒泡的過程就會一直延續(xù)到document的事件觸發(fā)才結(jié)束。

另外要說明的是,在IE5.5中冒泡的最高層DOM節(jié)點為document,IE6中則可以支持html節(jié)點。在Mozllia1.0及之后的版本也支持冒泡,而它則更可以冒到window窗口對象。

捕獲型事件(Event Capturing)

相對IE4.0,Netscape4.0則使用的是捕獲型事件的解決方案。這個事件觸發(fā)的過程則正好和冒泡相反——在捕獲型事件中,事件從最不精確的對象(document對象)開始觸發(fā),然后到最精確的對象。還是前面的示例,不過現(xiàn)在換由捕獲型事件觸發(fā)(當然你需要在Netscape或Firefox中測試)。

示例(2):點擊我觸發(fā)捕獲型事件流

示例(2)的XHTML代碼結(jié)構(gòu):

<span id="cnt1">
     <a href=”#1″ id=”link1″>點擊我觸發(fā)捕獲型事件流</a>
</span>

事件觸發(fā)的循序正好跟前面的冒泡相反,這里我就不贅述了。

DOM 事件流

這個事件流則是W3C制定一個標準規(guī)范,它同時支持兩種事件流模式,不過是先發(fā)生捕獲型事件流,再發(fā)生冒泡型事件流。

DOM事件流最獨特的是,它支持文本節(jié)點也觸發(fā)事件(IE中這不支持)。不過說實話,我現(xiàn)在還看不出來讓文本節(jié)點支持事件有什么作用。

最后要說的是,根據(jù)最近大家在開發(fā)的實踐過程中的運用,我們一般都采取冒泡型的事件流觸發(fā)方式,這點我們的IE做的比較成功。至于原因,我想你可以通過上面的解釋可以看出,畢竟我們給元素觸發(fā)事件,肯定是希望從我們最希望先觸發(fā)(從最精確的)的那個開始。而DOM的先捕獲后冒泡我覺得只能用讓我很疑惑來形容我的感受。因為如果按照DOM的事件流,我們的事件要被觸發(fā)2次,而我們一般都只會選擇一個類型的事件流,值希望觸發(fā)一次,很難理解當初W3C是怎么想的?!一個字——暈!可能我的理解能力有限,不過這是我的真是感受。

事件處理函數(shù)/監(jiān)聽函數(shù)

這里我不想做過多的介紹,我們知道在IE里使用attachEvent(”NAME_OF_EVENT_HANDLER”, fnHandler)給元素綁定事件,而在支持DOM事件流的瀏覽器里,則使用addEventListener(”NAME_OF_EVENT_HANDLER”, fnHandler, isCapture)。前面我控制FIREFOX中觸發(fā)捕獲事件流,就是通過設(shè)置isCapture(ture:捕獲;false:冒泡)做到的。還有就是我們傳統(tǒng)element.onclick或者element['on'+eventName],這個是所有瀏覽器都支持的事件綁定的監(jiān)聽器,而且我測試的結(jié)果XP下的IE6~8、Firefox2.0~3.5、Safari4.0、Opera9.6.4、Chrome2.0.180都是以冒泡的事件流觸發(fā)的。更老的瀏覽器我就沒有測試過了,不過根據(jù)《Pro Javascript Techniques》里介紹,老的瀏覽器使用onclick這樣的事件綁定,觸發(fā)的也是冒泡事件流。如果你有興趣可以淘下那些古董瀏覽器,測試一番。不過還是有不支持冒泡的事件的,下面我們就講講。

那些事件是支持冒泡,那些不支持?

這個是比較有意思的,這里的總結(jié)都來自PPK在YAHOO的演講《Javascript Event》(推薦大家一定看看,很經(jīng)典!),簡單總結(jié)PPK的內(nèi)容,基本上只有onload、unload、focus、blur、submit和change事件是不支持冒泡的,這也是我在前面說“一般使用冒泡事件流”。自然向keydown、keypress、keyup、click、dbclick、mousedown、mouseout、mouseover、mouseup、mousemove。用PPK的話說,那就是“Mouse and Key Events”支持冒泡,而Interface Events(也就是《Javascript高級程序設(shè)計》里的HTML(HTML是來構(gòu)建interface的)事件。)則只支持捕獲。

他又說了下是,click是“最安全的”事件,它即支持冒泡,又支持捕獲。鼠標事件可以觸發(fā)click,鍵盤事件也可以觸發(fā)click。還有就是在支持DOM事件的瀏覽器里,focus和blur是只支持捕獲的,所以如果你如果用到我下面給出的addEvent函數(shù),在給元素綁定focus或則blur事件時,bCapture一定要設(shè)置為true。那么這里就發(fā)生了一個問題,IE是不支持捕獲的,那不是觸發(fā)不了這連個事件?呵呵,是個嚴重的問題哦?不過在IE里使用focus和blur事件的時候,其實觸發(fā)的是IE的focusin和focusout,當然這兩個事件也是只支持冒泡的。

PPK雖然這么說,但是我還是想實踐一下,于是我這里這么處理了下,window.onfocus = function(){alert('ok')},lnkOne.onfocus = demoClick;有趣的事情發(fā)生了!在IE6里,當你點擊我的第一個示例鏈接,呵呵,視乎是即冒泡完了又捕獲了,在IE8中則只冒泡了,不過這個只是你點這個鏈接的時候發(fā)生的情況。接著我又算是試探性地“無意中”測試了下,點擊其他的應用程序,又一個讓我意想不到的情況發(fā)生了,居然先觸發(fā)了window.onfocus,接著觸發(fā)了lnk.onfocus?。∮谑俏伊⒖虦y試了IE6,一樣!視乎IE也“瘋狂”了一把,觸發(fā)了onfocus的捕獲哦,哈哈?。?!難道IE也支持捕獲,IE也瘋狂????。。?!還是這個現(xiàn)象有其他的解釋??疑惑?。浚????!呵呵,起初我確實這么想,讓我驚喜了一把,不過仔細想了想,只是事件執(zhí)行順序的原因造成了這樣的假象。

呵呵,原來在IE6里,點擊鏈接,先觸發(fā)了onfocus,彈出提示‘A',然后關(guān)閉彈出的提示框窗口時,窗口又獲得了焦點,又觸發(fā)了window的焦點事件。然后是觸發(fā)了A標簽的的click事件,然后關(guān)閉彈出的提示窗口時,又讓窗口獲得了焦點,然后又是A標簽獲得焦點。而IE8測試正確的,當觸發(fā)了click事件后,再關(guān)閉提示窗口的時候,就不在觸發(fā)window的focus。哎!空歡喜了一場,我還以為windows的IE支捕獲呢!!不過也不是完全沒有收獲,如果你也像我這么整了,你要注意IE6會折騰兩次的,不過只是在你點擊的時候才會這樣,如果用tab切換獲得焦點,就只會觸發(fā)A標簽的focus事件了。

還有在Firefox(我測試的最新的3.5)中,可千萬別window.onfocus,不然你就掛了!很抱歉用FIREFOX看我這篇帖子的人,OK了幾次后,你就掛了??!呵呵?。?!

What is ‘this'?

IE在前面給了我“驚喜”,this也給我驚喜。當然主要是我以前沒有注意到,但是YAHOO的工程師們早以發(fā)現(xiàn)了。this這個關(guān)鍵字是根據(jù)上下文來決定的,在我們的事件綁定的功能函數(shù)里,this應該是指向當前的元素節(jié)點對象,應該是一個Element對象。我想這個大家應該好理解:

示例代碼:


<span id="cnt0">
     <a href=”#1″ id=”link0″>點擊我觸發(fā)捕獲型事件流</a>
</span>

<script type=”text/javascript”>
var link = document.getElementById('link1′);
     link.onclick = function(){
          alert(this.tagName);
     };
</script>

這段代碼正式我在示例(1)中的處理方式,示例中this指向的a標簽這個element對象,所以我們可以得到a標簽的tagName這個屬性‘A'。示例(2)里,我使用一個兼容的事件監(jiān)聽函數(shù):


function addListener(el, event, fn, bCapture){
  var isCapture = bCapture ? bCapture : false;
  try {
    el.addEventListener(event, fn, isCapture);
  }
  catch (e) {
    try {
      el.attachEvent('on' + event, fn);
    }
    catch (e) {
      el['on' + event] = fn;
    }
  }
}

在我們的支持DOM事件流的瀏覽器里,我們也可以得到正確的提示this.tagName為‘A'。this出現(xiàn)問題就在IE中,當我們使用attachEvent給元素綁定事件,現(xiàn)在你點擊下面的鏈接:

示例(3):What is ‘this'?

示例代碼:
<span id=”cnt2″>
    <a href=”#1″ id=”link2″>What is ‘this'?</a>
</span>

function whatIsThis(){
    if (this === window) {
        alert('This is a window object');
    }
    alert('So, This.tagName is:'+ ‘‘'+ this.tagName +''。');
}

<script type=”text/javascript”>
var cntThree = document.getElementById('cnt2′), lnkThree = document.getElementById('link2′);

addListener(lnkThree, ‘click', whatIsThis);
addListener(cntThree, ‘click', whatIsThis);
</script>

看清楚了嗎?如果你在IE6~8中測試,那么你點的是window對象而不是一個a標簽。暈倒?。?!-_-! 所以你要小心,問題多多啊,要解決這個this關(guān)鍵字的問題,我給你的建議就是你可以考慮直接用傳統(tǒng)的'onclick'或者修改下前面的綁定事件監(jiān)聽的函數(shù):

修改后的代碼:

function addEvent(el, event, fn, obj, overrideContext, bCapture){
  var context = el, isCapture = bCapture ? bCapture : false, wrappedFn = null;

  if (overrideContext) {
    if (overrideContext === true) {
      context = obj;
    }
    else {
      context = overrideContext;
    }
  }
  wrappedFn = function(){
    return fn.call(context);
  };
  try {
    el.addEventListener(event, wrappedFn, isCapture);
  }
  catch (e) {
    try {
      el.attachEvent('on' + event, wrappedFn);
    }
    catch (e) {
      el['on' + event] = wrappedFn;
    }
  }
}

示例(4):再點點我,看我的‘this'是什么?

好了就這么多了,不知道對你有沒有幫助,最后說明下,本文中的部分觀點參考至《Javascript高級程序設(shè)計》(很好的一本書,推薦大家看看?。?,addEvent函數(shù)借鑒了YUI2.7的_addListener方法,這里也要謝謝YUI那些牛人,向他們致敬!

靜態(tài)頁訪問地址:http://img.jb51.net/online/jsevent/event.htm(如果你也想體驗下我的“驚喜”,請用IE6訪問,點擊第一個示例鏈接,但千萬不要用Firefox,否則會掛掉,別說我沒有提醒你?。?!)

相關(guān)文章

  • TypeScript中的混合(Mixin)示例詳解

    TypeScript中的混合(Mixin)示例詳解

    由于TypeScrip中的類不支持多繼承,所以引入了混合(Mixin)的特性,可以間接實現(xiàn)多繼承的效果,這篇文章主要介紹了一文弄懂TypeScript中的混合(Mixin),需要的朋友可以參考下
    2023-09-09
  • js表達式計算器代碼

    js表達式計算器代碼

    js表達式計算器代碼,需要的朋友可以參考下。
    2011-10-10
  • 如何去除js中的json存在的轉(zhuǎn)義字符\問題

    如何去除js中的json存在的轉(zhuǎn)義字符\問題

    這篇文章主要介紹了如何去除js中的json存在的轉(zhuǎn)義字符\問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • JavaScript將坐標字符串轉(zhuǎn)為數(shù)組的項目實踐

    JavaScript將坐標字符串轉(zhuǎn)為數(shù)組的項目實踐

    本文主要介紹了JavaScript將坐標字符串轉(zhuǎn)為數(shù)組的項目實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-01-01
  • 微信小程序?qū)崿F(xiàn)tabbar凹凸圓選中動畫效果實例

    微信小程序?qū)崿F(xiàn)tabbar凹凸圓選中動畫效果實例

    小程序日益增多的情況下,UI風格顯得越來越重要,下面這篇文章主要給大家介紹了關(guān)于微信小程序?qū)崿F(xiàn)tabbar凹凸圓選中動畫效果的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-09-09
  • js Canvas繪制圓形時鐘教程

    js Canvas繪制圓形時鐘教程

    這篇文章主要為大家詳細介紹了js Canvas繪制圓形時鐘教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • js模仿微信朋友圈計算時間顯示幾天/幾小時/幾分鐘/幾秒之前

    js模仿微信朋友圈計算時間顯示幾天/幾小時/幾分鐘/幾秒之前

    本篇文章主要介紹了js模仿微信朋友圈計算時間顯示幾天/幾小時/幾分鐘/幾秒之前的實例。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-04-04
  • uniapp中實現(xiàn)App自動檢測版本升級的示例代碼

    uniapp中實現(xiàn)App自動檢測版本升級的示例代碼

    本文主要介紹了uniapp中實現(xiàn)App自動檢測版本升級的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-01-01
  • 微信小程序h5頁面跳轉(zhuǎn)小程序的超詳細講解

    微信小程序h5頁面跳轉(zhuǎn)小程序的超詳細講解

    開發(fā)中涉及到一個需求,就是從一個預約票購買的頁面需要跳轉(zhuǎn)到?小程序,下面這篇文章主要給大家介紹了關(guān)于微信小程序h5頁面跳轉(zhuǎn)小程序的超詳細講解,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-02-02
  • echarts拖拽滑塊dataZoom-slider自定義樣式簡單適配移動端

    echarts拖拽滑塊dataZoom-slider自定義樣式簡單適配移動端

    在電腦端和移動端的數(shù)據(jù)展示中,針對移動端的特殊性,進行了一系列優(yōu)化措施,這篇文章主要介紹了echarts拖拽滑塊dataZoom-slider自定義樣式簡單適配移動端的相關(guān)資料,需要的朋友可以參考下
    2024-09-09

最新評論