中文字幕日韩一区二区_国产一区二区av_国产毛片av_久久久久国产一区_色婷婷电影_国产一区二区精品

Javascript 事件流和事件綁定

事件流

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

冒泡型事件(Dubbed Bubbling)

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

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

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

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

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

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

示例(1)

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

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

捕獲型事件(Event Capturing)

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

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

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

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

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

DOM 事件流

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

DOM事件流最獨(dú)特的是,它支持文本節(jié)點(diǎn)也觸發(fā)事件(IE中這不支持)。不過(guò)說(shuō)實(shí)話(huà),我現(xiàn)在還看不出來(lái)讓文本節(jié)點(diǎn)支持事件有什么作用。

最后要說(shuō)的是,根據(jù)最近大家在開(kāi)發(fā)的實(shí)踐過(guò)程中的運(yùn)用,我們一般都采取冒泡型的事件流觸發(fā)方式,這點(diǎn)我們的IE做的比較成功。至于原因,我想你可以通過(guò)上面的解釋可以看出,畢竟我們給元素觸發(fā)事件,肯定是希望從我們最希望先觸發(fā)(從最精確的)的那個(gè)開(kāi)始。而DOM的先捕獲后冒泡我覺(jué)得只能用讓我很疑惑來(lái)形容我的感受。因?yàn)槿绻凑誅OM的事件流,我們的事件要被觸發(fā)2次,而我們一般都只會(huì)選擇一個(gè)類(lèi)型的事件流,值希望觸發(fā)一次,很難理解當(dāng)初W3C是怎么想的?!一個(gè)字――暈!可能我的理解能力有限,不過(guò)這是我的真是感受。

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

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

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

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

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

PPK雖然這么說(shuō),但是我還是想實(shí)踐一下,于是我這里這么處理了下,window.onfocus = function(){alert('ok')},lnkOne.onfocus = demoClick;有趣的事情發(fā)生了!在IE6里,當(dāng)你點(diǎn)擊我的第一個(gè)示例鏈接,呵呵,視乎是即冒泡完了又捕獲了,在IE8中則只冒泡了,不過(guò)這個(gè)只是你點(diǎn)這個(gè)鏈接的時(shí)候發(fā)生的情況。接著我又算是試探性地“無(wú)意中”測(cè)試了下,點(diǎn)擊其他的應(yīng)用程序,又一個(gè)讓我意想不到的情況發(fā)生了,居然先觸發(fā)了window.onfocus,接著觸發(fā)了lnk.onfocus!!于是我立刻測(cè)試了IE6,一樣!視乎IE也“瘋狂”了一把,觸發(fā)了onfocus的捕獲哦,哈哈!!!難道IE也支持捕獲,IE也瘋狂???!!!!還是這個(gè)現(xiàn)象有其他的解釋?zhuān)浚恳苫螅。浚。浚。『呛牵鸪跷掖_實(shí)這么想,讓我驚喜了一把,不過(guò)仔細(xì)想了想,只是事件執(zhí)行順序的原因造成了這樣的假象。

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

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

What is ‘this'?

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

示例代碼:


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

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

這段代碼正式我在示例(1)中的處理方式,示例中this指向的a標(biāo)簽這個(gè)element對(duì)象,所以我們可以得到a標(biāo)簽的tagName這個(gè)屬性‘A'。示例(2)里,我使用一個(gè)兼容的事件監(jiān)聽(tīng)函數(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)問(wèn)題就在IE中,當(dāng)我們使用attachEvent給元素綁定事件,現(xiàn)在你點(diǎ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中測(cè)試,那么你點(diǎn)的是window對(duì)象而不是一個(gè)a標(biāo)簽。暈倒!!!-_-! 所以你要小心,問(wèn)題多多啊,要解決這個(gè)this關(guān)鍵字的問(wèn)題,我給你的建議就是你可以考慮直接用傳統(tǒng)的'onclick'或者修改下前面的綁定事件監(jiān)聽(tīng)的函數(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):再點(diǎn)點(diǎn)我,看我的‘this'是什么?

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

靜態(tài)頁(yè)訪(fǎng)問(wèn)地址:http://img.jb51.NET/online/jsevent/event.htm(如果你也想體驗(yàn)下我的“驚喜”,請(qǐng)用IE6訪(fǎng)問(wèn),點(diǎn)擊第一個(gè)示例鏈接,但千萬(wàn)不要用Firefox,否則會(huì)掛掉,別說(shuō)我沒(méi)有提醒你!!!)

JavaScript技術(shù)Javascript 事件流和事件綁定,轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 久久久亚洲综合 | 成人自拍视频网站 | 国产高清视频 | 成人在线视频免费观看 | 亚洲成人免费视频在线 | 成人区精品 | 国产美女高潮 | 98久久| 国产九九九 | 免费一二区| 国产aa | 天天天操操操 | 欧美精品在线一区二区三区 | 久久精品国产免费看久久精品 | 日韩免费av | 精品一区二区三区四区外站 | 亚洲国产一区二区三区, | 久久九九99 | 亚洲顶级毛片 | 欧美一级片在线看 | 欧美国产日韩在线 | 久久国产秒 | 欧美精品乱码久久久久久按摩 | 中文字幕精品一区二区三区精品 | 久久久久久国产精品三区 | 久久99精品国产麻豆婷婷 | 久久久国产视频 | 成人在线观看亚洲 | 91久久网站 | 日本一区二区电影 | 看a网站| 涩爱av一区二区三区 | 81精品国产乱码久久久久久 | 男女羞羞的网站 | 亚洲精品字幕 | 欧美日韩国产精品一区 | 91在线看片 | 日日噜噜噜夜夜爽爽狠狠视频, | 欧美极品在线 | 国产精品久久久久久久久动漫 | 国产精选一区 |