方法(一)(轉載的網絡資料)
需要了解的知識
首先,我們需要了解onchange和onpropertychange的不同:
IE下,當一個HTML元素的屬性改變的時候,都能通過 onpropertychange來即時捕獲。
onchange在屬性值改變時還必須使得當前元素失去焦點(onblur)才可以激活該事件。
onpropertychange 是IE瀏覽器的專屬方法
了解這一點后我們發現onpropertychange的效果就是我們想要的,可是很遺憾,它只在IE下有效果。我們能不能找到另外一個時間來代替onpropertychange呢?
經過翻閱資料得知,在其他瀏覽器下可以使用oninput事件來達到同樣的效果,真是太好了,我們只需要把IE瀏覽器區分出來就可以。
oninput的使用
下面我們先了解一下oninput如何使用。
如果您是將注冊時間直接寫在頁面里面,那么如下寫法就可以實現
<input type="text" name="textfield" oninput="alert(this.value);" onpropertychange="alert(this.value)" />
但是,將oninput寫在JS代碼中分離出來時與普通事件注冊的方法有些不同,必須使用addEventListener來注冊。
ttachEvent和addEventListener 的不同
說到這里我們再來了解一下 attachEvent和addEventListener 的使用方法:
attachEvent方法,為某一事件附加其它的處理事件。(不支持Mozilla系列)
addEventListener方法 用於 Mozilla系列
document.getElementById("btn").onclick = method1;
document.getElementById("btn").onclick = method2;
document.getElementById("btn").onclick = method3;
如果這樣寫,那么將會只有medhot3被執行
var btn1Obj = document.getElementById("btn1");
btn1Obj.attachEvent("onclick",method1);
btn1Obj.attachEvent("onclick",method2);
btn1Obj.attachEvent("onclick",method3);
執行順序為method3->method2->method1
如果是Mozilla系列,並不支持該方法,需要用到addEventListener
var btn1Obj = document.getElementById("btn1");
btn1Obj.addEventListener("click",method1,false);
btn1Obj.addEventListener("click",method2,false);
btn1Obj.addEventListener("click",method3,false);
執行順序為method1->method2->method3
了解了如何使用addEventListener來注冊oninput事件后我們再回到要解決的問題[划分瀏覽器]。
判斷IE瀏覽器
如何將IE區分出來呢?
這似乎是一個老生常談的問題,網絡中有很多找那個方法,歸類為兩類:
其一,是判斷瀏覽器的功能屬性。
其二,就是判斷傳統的 user-agent 字符串,這可能是最古老也是最流行的檢測方式。
在這里就不做深入了解了,我們這里用一種比較簡單的方法來判斷
if("\v"=="v") {
alert("IE");
}else{
alert("NO");
}
到目前為止我們遇到的問題就已經解決了,開始寫代碼來測試我們的思路是否能夠實現。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<meta name="auther" content="fq" />
<title>監聽輸入框值的即時變化 onpropertychange oninput</title>
<script type="text/javascript">
function immediately(){
var element = document.getElementById("mytext");
if("\v"=="v") {
element.onpropertychange = webChange;
}else{
element.addEventListener("input",webChange,false);
}
function webChange(){
if(element.value){document.getElementById("test").innerHTML = element.value};
}
}
</script>
</head>
<body>
直接寫在頁面中的示例:
<input type="text" name="textfield" oninput="document.getElementById('webtest').innerHTML=this.value;" onpropertychange="document.getElementById('webtest').innerHTML=this.value;" />
<div>您輸入的值為:<span id="webtest">還未輸入</span></div>
<br /><br /><br /><br /><br />
寫在JS中的示例:
<input type="text" name="textfield" id="mytext" />
<div>您輸入的值為:<span id="test">還未輸入</span></div>
<script type="text/javascript">
immediately();
</script>
</body>
</html>
更改為使用js往input里面加載值!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<meta name="auther" content="fq" />
<title>監聽輸入框值的即時變化 onpropertychange oninput</title>
<script type="text/javascript">
function immediately(){
var element = document.getElementById("mytext");
if("\v"=="v") {
element.onpropertychange = webChange;
}else{
element.addEventListener("input",webChange,false);
}
function webChange(){
if(element.value){document.getElementById("test").innerHTML = element.value};
}
}
function addValue(){
document.getElementById("mytext").value='dfdsafdsfsfsdfsdfdsf';
document.getElementById("mytext2").value='dfdsafdsfsfsdfsdfdsf';
}
</script>
</head>
<body>
<input type="button" id="txts" value="點擊加載值!" onclick="addValue();"/>
直接寫在頁面中的示例:
<input type="text" id="mytext2" name="textfield" oninput="document.getElementById('webtest').innerHTML=this.value;" onpropertychange="document.getElementById('webtest').innerHTML=this.value;" />
<div>您輸入的值為:<span id="webtest">還未輸入</span></div>
<br /><br /><br /><br /><br />
寫在JS中的示例:
<input type="text" name="textfield" id="mytext" />
<div>您輸入的值為:<span id="test">還未輸入</span></div>
<script type="text/javascript">
immediately();
</script>
</body>
</html>
實踐證明在IE中可以,在火狐中不可以!猜測可能是在火狐中不適用!於是使用了方法(二),方法(二)是比較笨重的一種手法,花了很多事情去測試和 更改方法二,但並沒有達到我要的效果!況且有計時器的存在,會影響到一定的效率問題!方法(二)並不是說不是好做法,只是適用於什么地方,有可能以后又需 要的地方還得使用呢!
那這樣的話,方法二我們都不用看了!
在不斷的嘗試中發現,方法一並不是不可用,只是,從網上看到的代碼存在一點問題。只能說,為什么這些文章上傳地有點草率了,給后來人帶了不少麻煩。就這么一點點的錯誤就可以讓我們不斷嘗試呀!為了不讓更多的人嘗試,希望這篇文章能給糾正一下!
其實,主要修改為:給方法加上()
document.getElementById("mytext").addEventListener("input",changeValue,false);
改為:document.getElementById("mytext").addEventListener("input",changeValue(),false);
以下為實驗代碼:(IE可行,火狐可行)
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'testInput.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script type="text/javascript">
function addValue(){
document.getElementById("mytext").value='dfdsafdsfsfsdfsdfdsf';
init();
}
function addValue2(){
document.getElementById("mytext").value='哈哈哈哈';
init();
}
function changeValue(){
document.getElementById("webtest").value=document.getElementById("mytext").value;
}
function init(){
if("\v"=="v"){//IE瀏覽器
document.getElementById("mytext").onpropertychange=changeValue;
}else{ // 其他瀏覽器
document.getElementById("mytext").addEventListener("input",changeValue(),false);
}
}
</script>
</head>
<body>
<input type="button" id="txts" value="點擊加載值!" onclick="addValue();"/>
<input type="button" id="txts2" value="第二次改加載值!" onclick="addValue2();"/>
<input type="text" name="textfield" id="mytext"/>
<div>您輸入的值為:<input id="webtest"></input></div>
</body>
</html>
(方法二)(轉載的網絡資料)
實時監聽js改變value,跨瀏覽器支持
有兩個文本框,其中一個只讀,另一個可以輸入。要求在可輸入文本框中輸入文本時,只讀文本框能夠獲得輸入的值,且只讀文本框旁邊出現提示信息,實時顯示只讀文本框的內容。
這個功能看是簡單,但其實並沒有想象的那么簡單。(注意,可輸入框的處理沒什么可討論的,關鍵是只讀框的處理)
一開始,我們一般會想到在只讀文本框上運用onchange事件。一試,發現onchange根本沒用,該事件是在文本框獲得焦點,然后內容改變失去焦點后才觸發的,現在在只讀文本框上根本沒有這些,它的內容是通過js改變的。於是,需要尋找另外的方法。
這時,在網上找到了onpropertychange事件。該事件在文本框屬性改變時觸發,不管是通過什么方式改變的。注意,是屬性改變,而不僅僅是value改變。一試,果然好使。然而,這個事件是IE專有的。WEB開發,必須得考慮瀏覽器的兼容問題。於是繼續摸索……
在網上有看到了另外一個事件:oninput。網上到處都是:fireFox中的該事件與IE中onpropertychange的事件等同。然而,我一 試,發現根本不等同。oninput事件在fireFox中似乎沒有起作用。經過一段時間測試,終於明白,原來oninput並非與 onpropertychange等同(網上到處到處亂轉貼,也不認真測試一下)。oninput只在用戶輸入值改變時觸發(即value改變),並非所 有屬性改變時觸發,而且,通過js改變value時,oninput不會觸發。這下郁悶了。好不容易看到點希望,又再次陷入了失望,還好沒有絕望……哎, 瀏覽器兼容問題真是麻煩。
左思右想,總有又有了眉目。對於fireFox等瀏覽器,可以通過定時器檢查只讀文本框的內容是否改變。測試后,終於大功告成。下面把代碼貼出來與大家分享。
在IE中的效果:
FireFox中的效果圖:
另外,我還在google Chrome測試也成功了(跟fireFox一樣的)。
HTML代碼:
view plaincopy to clipboardprint?
<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>
<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>
JavaScript代碼:
view plaincopy to clipboardprint?
$(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;" mce_style="color:red;">" + $("#jsUserName").val() + "</span></span>");
jsUserName = $("#jsUserName").val();
}
}
});
$(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;" mce_style="color:red;">" + $("#jsUserName").val() + "</span></span>");
jsUserName = $("#jsUserName").val();
}
}
});
說明:為了方便,js代碼使用了jQuery。不使用是一樣的。
另外,考慮性能問題,可以考慮何時啟動定時器和清除定時器以及定時器延時時間。
總結:
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不會觸發。
取巧方式:
jQuery.fn.val方法來賦值本來就不觸發change事件,但是可以手動觸發。
如:$('#inp').val(3353).change();