JavaScript DOM 学习第七章 表单的扩展


Posted in Javascript onFebruary 19, 2010

想法
假设你有一个在线的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)
Javascript 相关文章推荐
写了一个layout,拖动条连贯,内容区可为iframe
Aug 19 Javascript
JavaScript 原型学习总结
Oct 29 Javascript
js随机生成网页背景颜色的方法
Feb 26 Javascript
分享自己用JS做的扫雷小游戏
Feb 17 Javascript
Javascript的console['']常用输入方法汇总
Apr 26 Javascript
谈谈React中的Render Props模式
Dec 06 Javascript
js核心基础之构造函数constructor用法实例分析
May 11 Javascript
基于vue-cli搭建多模块且各模块独立打包的项目
Jun 12 Javascript
超详细的5个Shell脚本实例分享(值得收藏)
Aug 15 Javascript
15分钟学会vue项目改造成SSR(小白教程)
Dec 17 Javascript
Vue+webpack实现懒加载过程解析
Feb 17 Javascript
Vue2.0搭建脚手架
Mar 13 Vue.js
JavaScript DOM学习第六章 表单实例
Feb 19 #Javascript
JavaScript DOM 学习第五章 表单简介
Feb 19 #Javascript
JavaScript DOM学习第四章 getElementByTagNames
Feb 19 #Javascript
JavaScript DOM 学习第三章 内容表格
Feb 19 #Javascript
JavaScript DOM 学习第二章 编辑文本
Feb 19 #Javascript
JavaScript DOM学习第一章 W3C DOM简介
Feb 19 #Javascript
JavaScript 题型问答有答案参考
Feb 17 #Javascript
You might like
基于MySQL到MongoDB简易对照表的详解
2013/06/03 PHP
php使用类继承解决代码重复的问题
2015/02/11 PHP
WordPress中用于更新伪静态规则的PHP代码实例讲解
2015/12/18 PHP
php变量与数组相互转换的方法(extract与compact)
2016/12/02 PHP
PHP数据库操作三:redis用法分析
2017/08/16 PHP
浅析PHP开发规范
2018/02/05 PHP
Swoole实现异步投递task任务案例详解
2019/04/02 PHP
JavaScript 解析读取XML文档 实例代码
2009/07/07 Javascript
javascript 函数调用规则
2009/08/26 Javascript
js中将字符串转换成json的三种方式
2011/01/12 Javascript
12种不宜使用的Javascript语法整理
2013/11/04 Javascript
js判断IE浏览器版本过低示例代码
2013/11/22 Javascript
javascript如何使用bind指定接收者
2014/05/04 Javascript
javascript 自定义回调函数示例代码
2014/09/26 Javascript
JavaScript学习笔记之Function对象
2015/01/22 Javascript
在JavaScript中操作时间之getMonth()方法的使用
2015/06/10 Javascript
JS实现的几个常用算法
2016/11/12 Javascript
Mac中安装nvm的教程分享
2017/12/11 Javascript
JS定义函数的几种常用方法小结
2019/05/23 Javascript
javascript设计模式 ? 职责链模式原理与用法实例分析
2020/04/16 Javascript
[46:03]LGD vs VGJ.T 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python3编程实现获取阿里云ECS实例及监控的方法
2017/08/18 Python
python用pandas数据加载、存储与文件格式的实例
2018/12/07 Python
Python实现的各种常见分布算法示例
2018/12/13 Python
python实现微信小程序用户登录、模板推送
2019/08/28 Python
Python 用三行代码提取PDF表格数据
2019/10/13 Python
基于Python的接口自动化读写excel文件的方法
2021/01/15 Python
德国最大的网上足球商店:11teamsports
2019/09/11 全球购物
公司业务员岗位职责
2014/03/18 职场文书
计算机毕业生求职信
2014/06/10 职场文书
家庭困难证明
2014/10/12 职场文书
先进教育工作者事迹材料
2014/12/23 职场文书
农民工工资承诺书大全
2015/05/04 职场文书
运动会开幕式新闻稿
2015/07/17 职场文书
评奖评优个人先进事迹材料
2015/11/04 职场文书
2016年5月份红领巾广播稿
2015/12/21 职场文书