檢查表單數據是否被改變

表單是Web應用不可缺少的功能,它是服務器端與瀏覽器端數據交換的最基本的方法。你應該已經讀過很多關於HTML5和Javascript的表單標籤和數據驗證的文章,今天我們來討論下如何檢查表單數據是否被改變了。

爲什麼要檢查表單數據被改變?
有很多理由需要檢測表單數據是否有修改,讓我們來看一個很常見的場景,如果用戶修改了一個或多個表單域的值,當用戶跳離當前頁面時,你會給出用戶類似“你的修改尚未保存”的提示。你甚至可以給出用戶是否保存數據(比如Ajax)的選項。另外的情況,如果表單項沒有被修改,這時略去冗餘的表單驗證和數據發送將會增強用戶體驗。

Javascript onchange事件
爲HTML表單元素添加onchange事件處理器是一種可行的方法,這也是用的最多的,但是onchange的實現有一些問題存在:

1.如果用戶改變表單域的值,然後再修改回原始值,程序仍將認爲表單的修改已經發生。
2.如果表單項的值是通過Javascript動態修改的,onchange事件不會被自動觸發。
3.爲每一個表單元素增加onchange事件會引起性能問題,特別是較大的表單。
4.如果將表單元素從DOM中增加或移除,你需要相應的註冊或移除事件偵聽。
5.checkbox和radio的onchange事件在某些瀏覽器下不能按預期工作(你應該知道是哪個瀏覽器)。
6.除了onchange,還有更簡單有效的方案。
比較默認值
幸運的是,我們不需要爲了複雜的事件處理而寫過多的廢話,每個表單元素都有與該對象相關聯的默認值,即頁面加載完後表單控件顯示或者默認的數據值,該值可與用戶操作後的值進行對比以得出表單域的值是否發生了改變。

有點麻煩的是,不同類型的表單元素的默認值屬性(properties)不盡相同(做些判斷好了,並不影響什麼)

input和textarea
讓我們從簡單的元素開始,所有的textarea對象和除了checkbox、radio之外的 input對象都有一個名爲defaultValue的屬性,我們可以對比文本域的當前值和默認值是否相同以決定文本域的修改是否發生。

<!-- name input -->
<input type="text" id="name" name="name" value="www.csser.com" />
<script>
var name = document.getElementById("name");
if (n.value != n.defaultValue) alert("#name has changed");
</script>小提示:HTML4或XHTML中,文本域類型爲text、hidden、password或file的對象有defaultValue屬性。HTML5新的表單類型也有defaultValue屬性並且可以用相同的方式檢測默認值是否改變過,這些新表單元素包含email、tel、url、range、date、color和search。

checkbox和radio
checkbox和radio對象有一個defaultChecked屬性,其取值爲true或false,我們可以通過對比當前選中狀態與默認選中狀態進行比較,如:

<!-- newsletter opt-in -->
<input type="checkbox" id="optin" name="optin" checked="checked" />
<script>
var optin = document.getElementById("optin");
if (n.checked != n.defaultChecked) alert("#optin has changed by csser");
</script>注意checkbox和radio對象也有defaultValue屬性,但它僅被分配給元素的value特性(attribute)而不能標識當前的選中狀態。

下拉列表select
select控件通常用於提供一個下拉列表供用戶選擇,相比上面提到的控件,select有一點複雜,select元素本身並不具有默認值屬性,它的默認值存在於其option元素集合內。當頁面加載完畢,默認選中的option擁有selected特性,也就是這個option對象擁有defaultSelected屬性且值爲true。

我們可以從select節點的selectedIndex屬性取得當前選中的option的索引值,如果該option對象的defaultSelected屬性爲false,那麼select控件的值一定被修改了,如:

<!-- job title select box -->
<select id="job" name="job">
   <option>web designer</option>
   <option selected="selected">csser.com developer</option>
   <option>graphic artist</option>
   <option>IT professional</option>
   <option>other</option>
</select>
<script>
var job = document.getElementById("job");
if (!job.options[job.selectedIndex].defaultSelected) alert("#job has changed");
</script>上面的代碼在單選下拉列表並且有一個option擁有selected特性時運行正常,但我們需要留意一些陷阱:

1.如果沒有option被賦予selected特性,瀏覽器會將第一個設爲默認選中,但其defaultSelected屬性值卻爲false
2.如果兩個或更多option擁有selected特性(這不合邏輯,但是可能的),每個option都會擁有defaultSelected屬性且值爲true,但是瀏覽器僅能得到最後一個的默認值。
3.多重選擇控件允許用戶選擇任意個option:
<!-- skills multi-select box -->
<select id="skills" name="skills" multiple="multiple">
   <option selected="selected">HTML</option>
   <option selected="selected">CSSer</option>
   <option selected="selected">JavaScript</option>
   <option>PHP</option>
</select>多選下拉列表並不常用,因爲用多個checkbox可以提供更友好的界面,但是,如果使用多選下拉列表,多個option具有defaultSelected屬性且值爲true,select節點的selectedIndex屬性已經無效,所以需要循環每一個option才能判斷其selected屬性是否與其defaultSelected屬性相匹配。下面的代碼可以解決這個問題:

var  skills = document.getElementById("skills"),c = false, def = 0, o, ol, opt;
for (o = 0, ol = n.options.length; o < ol; o++) {
   opt = skills.options[o];
   c = c || (opt.selected != opt.defaultSelected);
   if (opt.defaultSelected) def = o;
}
if (c && !skills.multiple) c = (def != skills.selectedIndex);
if (c) alert("#skills has changed");上面這些就是本文介紹的如何檢測一個表單值是否改變的內容。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章