input事件在ie9以下不兼容問題完美解決


上周四好不容易加了幾天班把剛接手的一個pc頁面做完,周五同事說要兼容ie7~ie9,結果在上面一跑,輸入都沒法輸入。

我的需求是用6個span作為虛擬的密碼輸入框,實際上是用一個藏在頁面里的input來實現輸入的。如下圖

 

上面是我要實現的頁面,和頁面結構dom,就是點擊span的的父節點div的時候,要讓input獲取焦點。左邊是input,為了給大家展示就先不藏起來了,對了,千萬別用display:none來隱藏input,否則無法獲取焦點。

先來給大家復習一下input標簽的所有事件:

1. focus  當input 獲取到焦點時觸發

2. blur  當input失去焦點時觸發,注意:這個事件觸發的前提是已經獲取了焦點再失去焦點的時候會觸發相應的js

3. change 當input失去焦點並且它的value值發生變化時觸發

4. keydown 在 input中有鍵按住的時候執行一些代碼

5. keyup 在input中有鍵抬起的時候觸發的事件,在此事件觸發之前一定觸發了onkeydown事件

6. click  主要是用於 input type=button,當被點擊時觸發此事件

7. select  當input里的內容文本被選中后執行一段,只要選擇了就會觸發,不是非得全部選中

8. input  當input的value值發生變化時就會觸發,不用等到失去焦點(與onchange的區別)

 

開始我一直是用谷歌瀏覽器調試的,用的input事件,每次用戶的輸入和刪除都可以完美的監聽到,但一到ie8上,input事件就失效了,ie9以下版本根本不支持。

這時就需要用到ie專屬的onpropertychange事件

<input id="test" onpropertychange="alert('change');" type="text" />

經過調試后馬上就會發現,這個屬性是在元素的任何屬性變化時都會起作用,包括我們這里所提到的value,但至少是起作用了,那接下來的任務就是篩選出property為value的變化。以下的attachEvent是ie的綁事件方法,

還有一個屬性propertyname,相信每個人都能猜到這個屬性的意思了。對,這個就是用來獲取哪個屬性被修改的。我們只需要判斷是否是value被改變就ok了,所以當不上value時就return。

document.getElementById('test').attachEvent('onpropertychange',function(e) {
    if(e.propertyName!='value') return;
    /*
    
input值變化觸發回調方法
    ...
  */
});

但經過我測試,ie8上點backspace按鈕刪除的時候,不進事件啊,怎么ie會有這么多蛋疼的問題,查了很多資料都無法很好的解決這個問題,只能自己來用keydown事件實現了。

$('input').bind('keydown',function(e){
      if(e.keyCode==8||e.keyCode==46){ //處理回退與刪除    
     //每刪除input末位一個字符時的回調方法
  } 
}) 

但是keydown事件,每次進入,都是在value里的最后一個字符未被刪除之前,比如我開始輸入了123,我按下刪除按鈕,斷點進了keydown事件,但此時獲取input的value還是123,這該如何是好。於是我先記錄刪除前的value,再在事件里面獲取刪除后的value,如果刪除后的value長度比刪除前的小,就進我的回調方法。

var len=self.setpsd.value().length;  //獲取刪除前長度
this.setpsd.bind('keydown',function(e){
       if(e.keyCode==8||e.keyCode==46){
               var newlen=self.setpsd.value().length;  //獲取刪除后長度
               if(newlen<len){
                     //每刪除input末位一個字符時的回調方法
               }
       }
})                

處理完以上這些,又遇到個問題,就是在ie8中當我輸入過程中,點了下頁面其他地方,失去了焦點,再點到span上,重新獲取焦點,但此時光標不在我已輸入字符的后面,而跑到最前面去了,這樣我就死活刪除不了已輸入的內容了,因為用戶是無法操作那藏起來的input的。

要操作光標的位置我們都有耳聞,textRange對象,沒錯,你答對了一半。因為textRange是IE私有對象

那么我們怎么獲取textRange對象呢?查看IE的DHTML文檔。

ie_creatTextRange.png

從文檔中我們得到了creatTextRange方法可以創建textRange對象。

通過文檔api的篩選,我們看到,紅框中的幾個方法對我們有用。這里,我提一下select方法,select方法文檔上的翻譯是“將當前選中區置為當前對象”。這句話怎么理解呢?

 這句話是說,我們通過createTextRange方法創建了textRange對象,注意是創建,也就是說原本不存在這個對象。然后我們使用這個對象的collapse或者move,moveStart方法的時候,操作的都是textRange對象,而最后的狀態表現是在input對象上的,select方法的作用就是,把textRange對象上的操作影印到input對象上的文本區域中。

  明白了select方法,我們看collapse方法:將插入點移動到當前范圍的開始或者結束。

collapse.png

有點英語水平的,上面的介紹應該能看懂,就是說我們要想讓光標移動到末尾話應該傳入false,

那么使用collapse的方法代碼應該是(我們定義是在itext上的onfocus事件)

document.getElementById("psd").onfocus=focushandler;
    function focushandler(){
        if(this.createTextRange){
            var rg=this.createTextRange();
            rg.collapse(false);
            rg.select();
        }
    }

就這么幾句,完美解決我的問題,不需要用到什么move、moveStart、moveEnd方法。更詳細的請看http://webfront-js.com/articaldetail/29.html

對了,最后介紹下如果判斷是ie瀏覽器,最簡單的方法就是

if(!!document.all){
    //ie瀏覽器處理
}

在 IE 中 document.all 的布爾值是 true ,其他瀏覽器都是 false。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM