想法
假設你有一個線上的CD評級工具。你希望使用者查看他們喜歡的所有CD。但是你怎麼知道使用者平均會查看多少張呢?你在這個頁面上需要添加多少欄位呢?
在W3CDOM出現之前這確實是一個問題。假設你放置了7張CD。但是使用者很可能只想查看一張,太多可能會嚇著使用者,而有些使用者想查看自己的所有CD,這樣就不得不反覆提交很多次。這確實很煩人。
只有使用W3C DOM才能讓使用者決定產生多少個欄位。這個效果和之前的大不相同。
例子
當你點擊發送的時候,表單就會把得到的所有參數以數組的形式發送。這用來檢查是否真正的發送到了伺服器端。不幸的是,mac版的IE和Safari不能發送。
IE的問題
windows下的IE有兩個嚴重的問題:
第一個問題是所有產生的單選框都同屬於一個數組,即使他們的names不同。這樣使用者就只能在所有的單選框裡面選擇一個。也就是說你不能在產生的表單裡面實用單選框。
有讀者說通過innerHTML產生的單選框沒有問題。如果你非要實用單選框的話,你可以試試。
第二個問題是產生的表單通過傳統的document.forms無法訪問:IE沒有在數組裡麵包含他們。這個可以通過給他們設定ID來解決。
解釋
表單的HTML代碼:
複製代碼 代碼如下:<div id="readroot" style="display: none">
<input type="button" value="Remove review"
onclick="this.parentNode.parentNode.removeChild(this.parentNode);" /><br /><br />
<input name="cd" value="title" />
<select name="rankingsel">
<option>Rating</option>
<option value="excellent">Excellent</option>
<option value="good">Good</option>
<option value="ok">OK</option>
<option value="poor">Poor</option>
<option value="bad">Bad</option>
</select><br /><br />
<textarea rows="5" cols="20" name="review">Short review</textarea>
<br />Radio buttons included to test them in Explorer:<br />
<input type="radio" name="something" value="test1" />Test 1<br />
<input type="radio" name="something" value="test2" />Test 2
</div>
<form method="post" action="/cgi-bin/show_params.cgi">
<span id="writeroot"></span>
<input type="button" id="moreFields" value="Give me more fields!" />
<input type="submit" value="Send form" />
</form>
真正的表單項目在ID為readroot的DIV並且display值為none。這個DIV是一個模板,使用者不能修改。當使用者需要更多的表單的時候我們就複製這個模板然後添加在表單之後。我們在一開始的就載入,這樣當使用者開啟頁面的時候就能看到。
這個DIV在表單之外,所以當使用者提交表單的時候,這個模板的內容不會被提交。
ID為writeroot的SPAN是一個標記。新的產生的表單就插入在他的前面。
添加表單項目
下面的代碼可以再需要的時候用來添加表單項目: 複製代碼 代碼如下:var counter = 0;
function moreFields() {
counter++;
var newFields = document.getElementById('readroot').cloneNode(true);
newFields.id = '';
newFields.style.display = 'block';
var newField = newFields.childNodes;
for (var i=0;i<newField.length;i++) {
var theName = newField[i].name
if (theName)
newField[i].name = theName + counter;
}
var insertHere = document.getElementById('writeroot');
insertHere.parentNode.insertBefore(newFields,insertHere);
}
window.onload = moreFields;
首先我們需要一個計數器counter,因為所有的表單項都應該有唯一的一個名字。我們把計數器的值添加在產生name後面。初始化計數器: 複製代碼 代碼如下: var counter = 0;
然後是實際的函數。我們給計數器加1: 複製代碼 代碼如下:function moreFields() {
counter++;
然後複製我們的模板,移除ID,並且把display設定為block。readroot應該是整個文檔裡面唯一的ID,複製模板後應該顯示出來讓使用者看到。 複製代碼 代碼如下:var newFields = document.getElementById('readroot').cloneNode(true);
newFields.id = '';
newFields.style.display = 'block';
我們遍曆這個拷貝的子項目: 複製代碼 代碼如下:var newField = newFields.childNodes;
for (var i=0;i<newField.length;i++) {
如果子項目有name屬性,那麼我們就在name值上加上計數器的值,以保證他的唯一性: 複製代碼 代碼如下:var theName = newField[i].name
if (theName)
newField[i].name = theName + counter;
}
現在這個拷貝已經準備好插入了。我們把他插入到writeroot之前: 複製代碼 代碼如下:var insertHere = document.getElementById('writeroot');
insertHere.parentNode.insertBefore(newFields,insertHere);
}
然後我們在頁面載入的時候就執行一次,這樣使用者進入的時候就能看到: 複製代碼 代碼如下: window.onload = moreFields;
移除表單項
每一個模板的拷貝都有一個移除按鈕: 複製代碼 代碼如下: <input type="button" value="Remove review"
onclick="this.parentNode.parentNode.removeChild(this.parentNode);" />
點擊這個按鈕就會從移除他的父元素(DIV)。整個產生的表單就都會消失,並且不會再出現。
翻譯地址:http://www.quirksmode.org/dom/domform.html
轉載請保留以下資訊
作者:北玉(tw:@rehawk)