第二十八課:focusin與focusout,submit,oninput事件的修復

focusin與focusout瀏覽器

這兩個事件是IE的私有實現,能冒泡,它表明得到焦點或失去焦點的事件。如今只有Firefox不支持focusin,focusout事件。其實另外兩個事件focus和blur是用來實現獲取焦點和失去焦點的事件,可是因爲這兩個事件不能冒泡,因此不少瀏覽器就使用focusin,focusout來代替它,可是火狐不支持這兩個事件,因此暫時還不能使用focusin,focusout事件代替focus和blur事件。異步

那麼兼容性寫法是怎麼樣的呢?以下:函數

if (document.addEventListener) {   //若是是W3C的方式,就用捕獲的機制(從父元素到目標元素),來實現冒泡的機制(從目標元素到父元素),這樣父元素就能得到目標元素的focus和blur事件了
  el.addEventListener('focus', focusHandler, true);   
  el.addEventListener('blur', blurHandler, true);
} else {
  el.onfocusin = focusHandler;   //IE不支持捕獲階段,可是支持focusin和focusout這兩個事件,這兩個事件自己就是冒泡的。所以父元素能得到目標元素的focus和blur事件
  el.onfocusout = blurHandler;
}spa

固然另一種寫法是:代理

if("onfocusin" in form){orm

  addEvent(form,"focusin",focusHandler,false);   //第一個參數爲綁定的元素,第二個是事件類型,第三個是事件處理函數,第四個是是否捕獲階段,false表明冒泡。對象

  addEvent(form,"focusout",blurHandler,false);事件

}element

else{rem

  addEvent(form,"focus",focusHandler,true);   //第一個參數爲綁定的元素,第二個是事件類型,第三個是事件處理函數,第四個是是否捕獲階段,true表明捕獲。

  addEvent(form,"blur",blurHandler,true);

}

submit事件

在IE6-8下,submit不會冒泡到頂層,它只執行form元素的submit回調,冒泡到form元素,就提交跳轉。submit事件跟鼠標事件和鍵盤事件不同,它是一種複合事件,既能夠經過鼠標事件實現,也能夠經過鍵盤事件實現。

若是咱們經過鼠標或者鍵盤來觸發submit事件:在IE9+以及其餘標準瀏覽器會觸發form元素以及祖先元素一直到window的submit事件,纔會跳轉。IE8-,只觸發到form元素的submit事件就跳轉了。它們都不會觸發form元素以內的元素綁定的submit事件的回調方法,所以submit事件的回調方法只能放在form元素中。

怎麼來解決這個兼容性問題呢:

咱們對submit事件進行處理,若是觸發submit事件時,使用的是事件代理,那麼就在代理元素上綁定兩個事件,click,keypress。若是是鍵盤事件,根據keyCode是否爲13(鍵盤事件keypress,當keyCode=13時,就表明用戶按了enter按鍵,就表明用戶正在觸發submit事件,提交數據。這裏的enter按鍵須要是在input元素中觸發才行,IE下type=file的input也能夠。),若是是點擊事件,根據input元素的type屬性值是不是submit,image(鼠標click事件,當點擊的input是submit或image類型時,就表明用戶正在觸發submit事件,提交數據)。是的話,就手動模擬冒泡(由於submit事件在IE6-8下只能冒泡到form元素,所以手動模擬)。把submit事件一直模擬冒泡到window對象(這時代理元素就能觸發submit事件了)。

若是最後都沒有阻止默認行爲,就經過el.submit()方法提交數據,進行跳轉。el.submit()方法,不會執行submit回調的(也就是說執行el.submit方法會提交數據,進行跳轉,可是不會執行submit的事件處理函數),而其餘的click,blur,focus這樣的DOM方法會同時執行回調和默認行爲的。

reset事件跟submit事件同樣,解決辦法也同樣,只是keyCode值不同或者type的屬性值不同而已。

oninput事件

在作搜索框的智能提示,微博發佈區@好友出現列表等功能時,咱們須要監聽輸入框內部的變化。若是使用change事件,只能等失去焦點時纔會觸發回調,若是使用keydown,keypress,keyup,這幾個鍵盤事件來監聽,就監聽不了右鍵的複製,剪貼,粘貼這些操做,這時咱們就須要oninput事件了。

oninput事件是W3C提出來的,IE9才支持,但IE9對回退鍵,粘貼複製操做的監聽也失靈,解決辦法,用onkeydown解決回退鍵,oncut和onpaste解決粘貼複製操做(也能夠經過onselectionchange事件來解決)。IE6-8下經過onpropertychange事件監聽元素一切屬性與特性的變化,所以能夠經過它模擬oninput事件(事件對象的propertyName屬性獲取當前變更的屬性名)

兼容寫法以下:

if(window.addEventListener){    //IE9+,以及其餘標準瀏覽器

  element.addEventListener("input",callback);

}

else{

  element.attachEvent("onpropertychange",function(e){   //若是是IE6-8,input元素上的任何屬性有變化就會觸發

    if(e.propertyName === "value"){    //若是是value屬性有變化,就會觸發回調

      callback();

    }

  })

}

if(IE9){   //解決IE9下,input事件對回退,粘貼複製操做的失靈

  var selectionchange = function(e){

    if(e.type === "focus"){

      document.addEventListener("selectionchange",callback);

    }else{

      document.removeEventListener("selectionchange",callback);

    }

  }

  element.addEventListener("focus",selectionchange);   //input得到焦點就綁定document的selectionchange事件,所以在input中的任何操做都會冒泡到document中

  element.addEventListener("blur",selectionchange);   //input失去焦點,就移除這個綁定事件

}

跟事件相關的操做已經所有講完了,若是想作兼容性的操做,仍是有點複雜的,你們認真看吧。

下面的課程將會講到異步處理,敬請期待。

 

 

 

加油!

相關文章
相關標籤/搜索