input事件在ie9以下不兼容問題完美解決
上周四好不容易加了幾天班把剛接手的一個pc頁面做完,周五同事說要兼容ie7~ie9,結果在上面一跑,輸入都沒法輸入。
我的需求是用6個span作為虛擬的密碼輸入框,實際上是用一個藏在頁面裏的input來實現輸入的。如下圖
上面是我要實現的頁面,和頁面結構dom,就是點擊span的的父節點div的時候,要讓input獲取焦點。左邊是input,為了給大家展示就先不藏起來了,對了,千萬別用display:none來隱藏input,否則無法獲取焦點。
先來給大家復習一下input標簽的所有事件:
1. focus 當input 獲取到焦點時觸發
2. blur 當input失去焦點時
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的綁事件方法。
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文檔。
從文檔中我們得到了creatTextRange方法可以創建textRange對象。
通過文檔api的篩選,我們看到,紅框中的幾個方法對我們有用。這裏,我提一下select方法,select方法文檔上的翻譯是“將當前選中區置為當前對象”。這句話怎麽理解呢?
這句話是說,我們通過createTextRange方法創建了textRange對象,註意是創建,也就是說原本不存在這個對象。然後我們使用這個對象的collapse或者move,moveStart方法的時候,操作的都是textRange對象,而最後的狀態表現是在input對象上的,select方法的作用就是,把textRange對象上的操作影印到input對象上的文本區域中。
明白了select方法,我們看collapse方法:將插入點移動到當前範圍的開始或者結束。
有點英語水平的,上面的介紹應該能看懂,就是說我們要想讓光標移動到末尾話應該傳入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。
input事件在ie9以下不兼容問題完美解決