前端頁面開發的非常多情況下都須要實時監聽文本框輸入,比方騰訊微博編寫140
字的微博時輸入框會動態顯示還能夠輸入的字數。
過去一般都使用onchange/onkeyup/onkeypress/onkeydown
實現,可是這存在着一些不好的用戶體驗。
比方onchange
事件僅僅在鍵盤或者鼠標操作改變對象屬性,且失去焦點時觸發,腳本觸發無效;而onkeydown/onkeypress/onkeyup
在處理複製、粘貼、拖拽、長按鍵(按住鍵盤不放)等細節上並不完好。
onpropertychange
屬性可在某些情況下解決上面存在的問題,不用考慮是否失去焦點。無論js
操作還是鍵盤鼠標手動操作,僅僅要HTML
元素屬性發生改變就可以馬上捕獲到。遺憾的是。onpropertychange
爲IE專屬的。其它瀏覽器下假設想要實現這一實時監聽的需求。就要用到HTML5
中的標準事件oninput
,只是IE9
下面的瀏覽器是不支持oninput
事件的。
所以我們須要綜合oninput
和onpropertychange
二者來實現文本區域實時監聽的功能。舉比例如以下:
例1、對支持oninput
的瀏覽器用oninput
。其它瀏覽器(IE6/7/8
)使用onpropertychange
:
var testinput = document.createElement('input');
if('oninput' in testinput){
object.addEventListener("input",fn,false);
}else{
object.onpropertychange = fn;
}
例2、對全部ie使用onpropertychange
,其它瀏覽器用oninput
:
var ie = !!window.ActiveXObject;
if(ie){
object.onpropertychange = fn;
}else{
object.addEventListener("input",fn,false);
}
彙總onchange
onpropertychange
和oninput
事件的差別:
1、onchange
事件與onpropertychange
事件的差別:
onchange
事件在內容改變(兩次內容有可能還是相等的)且失去焦點時觸發;onpropertychange
事件卻是實時觸發,即每添加或刪除一個字符就會觸發。通過js
改變也會觸發該事件。可是該事件IE
專有。
2、oninput
事件與onpropertychange
事件的差別:
oninput
事件是IE之外的大多數瀏覽器支持的事件。在value
改變時觸發,實時的,即每添加或刪除一個字符就會觸發,然而通過js
改變value
時。卻不會觸發;onpropertychange
事件是不論什麼屬性改變都會觸發的,而oninput
卻僅僅在value
改變時觸發,oninput
要通過addEventListener()
來註冊,onpropertychange
註冊方式跟一般事件一樣。(此處都是指在js
中動態綁定事件,以實現內容與行爲分離)
3、oninput
與onpropertychange
失效的情況:
(1)oninput
事件:a). 當腳本中改變value
時。不會觸發。b).從瀏覽器的自己主動下拉提示中選取時,不會觸發。
(2)onpropertychange
事件:當input
設置爲disable=true
後。onpropertychange
不會觸發。
以下引用一篇譯文:
HTML5
將oninput
事件標準化了,該事件用來檢測用戶的輸入狀態。當然,通過使用onkeydown
或者onkeyup
作爲取代也是能夠的。這些事件設計本意也並不是如此,參見詳情。
全部的現代瀏覽器支持oninput
,當中包含IE9
。
對於那些老式瀏覽器,在不支持該事件時用keydown
作爲優雅降級。
不幸的是,檢測瀏覽器對該oninput
事件的支持性並不easy
。
假定瀏覽器支持oninput
。那麼下面這段js代碼的返回值爲true
,否則爲false
。
'oninput' in document.createElement('input')
這段代碼在大多數瀏覽器中正常執行,除了Firefox(見bug #414853),故仍舊須要爲oninput
作瀏覽器特性檢測。除此以外就不是必需爲其它瀏覽器作特性檢測了,僅僅需爲input
和keydown
綁定事件。並在oninput
事件觸發之後刪除onkeydown
就可以。示比例如以下:
someElement.oninput = function() {
el.onkeydown = null;
// Your code goes here
};
someElement.onkeydown = function() {
// Your code goes here
}
keydown
事件僅會被觸發一次(在oninput
事件觸發前)。之後再觸發oninput
。儘管並不完美。但總比寫上一大堆oninput
特性檢測代碼要好些吧。