一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

Javascript 事件流和事件綁定

事件流

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

冒泡型事件(Dubbed Bubbling)

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

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

示例(1)的XHTML代碼結構:

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

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

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

示例(1)

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

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

捕獲型事件(Event Capturing)

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

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

示例(2)的XHTML代碼結構:

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

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

DOM 事件流

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

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

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

事件處理函數/監聽函數

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

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

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

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

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

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

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

What is ‘this'?

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

示例代碼:


<span id="cnt0">
     <a href=”#1″ id=”link0″>點擊我觸發捕獲型事件流</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)里,我使用一個兼容的事件監聽函數:


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出現問題就在IE中,當我們使用attachEvent給元素綁定事件,現在你點擊下面的鏈接:

示例(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關鍵字的問題,我給你的建議就是你可以考慮直接用傳統的'onclick'或者修改下前面的綁定事件監聽的函數:

修改后的代碼:

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高級程序設計》(很好的一本書,推薦大家看看!),addEvent函數借鑒了YUI2.7的_addListener方法,這里也要謝謝YUI那些牛人,向他們致敬!

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

JavaScript技術Javascript 事件流和事件綁定,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 亚洲 激情 | 成人三级视频在线观看 | 亚洲色吧 | 日韩国产一区二区 | 在线国产91 | 日韩久草| 激情国产 | 一色屋色费精品视频在线观看 | 婷婷在线视频 | 色资源二区在线视频 | 在线免费观看一区二区三区 | 国产91系列 | 一个色综合网站 | 日本成人网址 | 亚洲1区2区3区4区 | 激情网站免费 | 性感美女一级毛片 | 中国一级特黄真人毛片免费看 | 伊人热人久久中文字幕 | 免费在线观看一区二区 | 日韩一区二区在线免费观看 | 婷婷亚洲天堂 | 四虎国产在线观看 | 国产免费一区二区三区在线观看 | 综合国产 | 天天色天天爱 | se成人国产精品 | 中文字幕在线精品视频万部 | 日本网址在线观看 | 欧美yw193.c㎝在线观看 | 狠狠色丁香久久综合五月 | 精品二区 | 久久国产欧美日韩高清专区 | 国产精品欧美激情在线播放 | 亚洲激情在线观看 | 亚洲乱码在线播放 | 久久精品99视频 | 美女很黄免费 | 国色天香网站 | 91伊人国产 | 国产一区二区三区久久 |