今天同事測試發現項目中一個小bug,而後我負責解決。研究了不短的時間,終於搞定了,有點激動。呵呵。拿出來與你們分享。
想要實現的功能大概是這樣的:
有兩個文本框,其中一個只讀,另外一個能夠輸入。要求在可輸入文本框中輸入文本時,只讀文本框可以得到輸入的值,且只讀文本框旁邊出現提示信息,實時顯示只讀文本框的內容。
這個功能看是簡單,但其實並無想象的那麼簡單。(注意,可輸入框的處理沒什麼可討論的,關鍵是隻讀框的處理)瀏覽器
一開始,咱們通常會想到在只讀文本框上運用onchange事件。一試,發現onchange根本沒用,該事件是在文本框得到焦點,而後內容改變失去焦點後才觸發的,如今在只讀文本框上根本沒有這些,它的內容是經過js改變的。因而,須要尋找另外的方法。 app
這時,在網上找到了onpropertychange事件。該事件在文本框屬性改變時觸發,不論是經過什麼方式改變的。注意,是屬性改變,而不只僅是value改變。一試,果真好使。然而,這個事件是IE專有的。WEB開發,必須得考慮瀏覽器的兼容.因而繼續摸索…… 函數
在網上有看到了另一個事件:oninput。網上處處都是:fireFox中的該事件與IE中onpropertychange的事件等同。然而,我一試,發現根本不等同。oninput事件在fireFox中彷佛沒有起做用。通過一段時間測試,終於明白,原來oninput並不是與 onpropertychange等同(網上處處處處亂轉貼,也不認真測試一下)。oninput只在用戶輸入值改變時觸發(即value改變),並不是全部屬性改變時觸發,並且,經過js改變value時,oninput不會觸發。這下鬱悶了。好不容易看到點但願,又再次陷入了失望,還好沒有絕望……哎,瀏覽器兼容真是麻煩。
冥思苦想,總有又有了眉目。對於fireFox等瀏覽器,能夠經過定時器檢查只讀文本框的內容是否改變。測試後,終於大功告成。下面把代碼貼出來與你們分享。性能
在IE中的效果:
在FireFox中的效果:
另外,我還在google Chrome測試也成功了(跟fireFox同樣的)。
HTML代碼測試
<table>
<tr>
<td>此處值經過js設置:</td>
<td><input id="jsUserName" type="text" name="jsUserName" readonly/></td>
</tr>
<tr>
<td>此處輸入值:</td>
<td><input id="userName" type="text" name="userName"/></td>
</tr>
</table>this
Javascript代碼google
$(function()
{
var jsUserName = "";
if($.browser.msie) // IE瀏覽器
{
$("#userName").get(0).onpropertychange = setJsUserName;
$("#jsUserName").get(0).onpropertychange = handle;
}
else // 其餘瀏覽器
{
var intervalName; // 定時器句柄
$("#userName").get(0).addEventListener("input",setJsUserName,false);
// 得到焦點時,啓動定時器
$("#userName").focus(function(){
intervalName = setInterval(handle,1000);
});
// 失去焦點時,清除定時器
$("#userName").blur(function()
{
clearInterval(intervalName);
});
}
// 設置jsUserName input的值
function setJsUserName()
{
$("#jsUserName").val($(this).val());
}
// jsUserName input的值改變時執行的函數
function handle()
{
// IE瀏覽器此處判斷沒什麼意義,但爲了統一,且提取公共代碼而這樣處理。
if($("#jsUserName").val() != jsUserName)
{
$("#toolTip").remove();
$("#jsUserName").parent().append("<span id='toolTip'>看到這裏的信息代表,經過js改變input的值也能響應相應事件:<span style='color:red;'>" + $("#jsUserName").val() + "</span></span>");
jsUserName = $("#jsUserName").val();
}
}
});
spa
說明:爲了方便,js代碼使用了jQuery。不使用是同樣的。
另外,考慮性能,能夠考慮什麼時候啓動定時器和清除定時器以及定時器延時時間。
firefox
總結:事件
一、onchange事件與onpropertychange事件的區別: onchange事件在內容改變(兩次內容有可能仍是相等的)且失去焦點時觸發;onpropertychange事件倒是實時觸發,即每增長或刪除一個字符就會觸發,經過js改變也會觸發該事件,可是該事件IE專有。 二、oninput事件與onpropertychange事件的區別: oninput事件是IE以外的大多數瀏覽器支持的事件,在value改變時觸發,實時的,即每增長或刪除一個字符就會觸發,然而經過js改變 value時,卻不會觸發;onpropertychange事件是任何屬性改變都會觸發的,而oninput卻只在value改變時觸發,oninput要經過addEventListener()來註冊,onpropertychange註冊方式跟通常事件同樣。(此處都是指在js中動態綁定事件,以實現內容與行爲分離) 三、oninput與onpropertychange失效的狀況: (1)oninput事件:a). 當腳本中改變value時,不會觸發;b). 從瀏覽器的自動下拉提示中選取時,不會觸發。 (2)onpropertychange事件:當input設置爲disable=true後,onpropertychange不會觸發。