客户端JavaScript的存在使得静态的HTML文档变成了交互式的Web应用。脚本化Web页面内容是JavaScript的核心目标。
1. DOM概览
文档对象模型(Document Object Model,DOM),是表示和操作HTML和XML文档内容的基础API
DOM的基本架构
- 在文档中查询或选取单独的元素。
- 将文档作为节点树来遍历,如何找到任何文档元素的祖先、兄弟和后代元素。
- 查询和设置文档元素的属性。
- 查询、设置和修改文档内容。
- 通过创建、插入和删除节点来修改文档结构
- 与HTML表单一起工作
1.1 DOM的树状表示
<!DOCTYPE html>
<html>
<head>
<title>Sample Document</title>
</head>
<body>
<h1>An HTML Document</h1>
<p>This is a<i>simple</i>document.</p>
</body>
</html>
下图是此文档DOM表示的树状图
图中的每个方框是文档的一个节点,它表示一个Node对象
上面例子包含3种不同类型的节点。树形的根部是Document节点,它代表整个文档。代表HTML元素的节点是Element节点,代表文本的节点是Text节点。Document、Element和Text是Node的子类
Document类型代表一个HTML或XML文档,Element类型代表该文档中的一个元素。HTMLDocument和HTMLElement子类只是针对于HTML文档和元素。
1.2 Node及其在类型层次结构中的子类型
上图展示了Node及其在类型层次结构中的子类型
- Comment节点代表HTML或XML的注释。由于注释基本上是文本字符串,因此它们很像表示文档中显示文本的Text节点。
- DocumentFragment类在实际文档中并不存在的一种节点:它代表一系列没有常规父节点的节点
- DOM也定义了一些不经常使用的类型,如像代表doctype声明和XML处理指令等类型。
2. 选取文档元素
为了操作文档中的元素,必须通过某种方式获得或选取这些引用文档元素的Element对象。DOM定义许多方式来选取元素:
- 用指定的id属性;
- 用指定的name属性;
- 用指定的标签名字;
- 用指定的CSS类;
- 匹配指定的CSS选择器。
2.1 用指定的id属性
可以用Document对象的getElementById()方法选取一个基于唯一ID的元素。
var section1=document.getElementById("section1");
2.2 用name选取元素
基于name属性的值选取HTML元素,可以使用Document对象的getElementsByName()方法,它返回一个NodeList对象。
和id不一样的是name属性只在少数HTML元素中有效,包括表单、表单元素、<iframe>和<img>元素。
var radiobuttons=document.getElementsByName("favorite_color");
2.3 用HTML标签名选取元素
Document对象的getElementsByTagName()方法可用来选取指定类型(标签名)的所有HTML或XML元素,返回一个NodeList对象。
var spans=document.getElementsByTagName("span");
(1)NodeList
一个节点的集合,既可以包含元素和其他节点(注释节点、文本节点等)。
(2)HTMLCollection
元素集合, 只有Element
- 给getElementsByTagName()传递通配符参数“*”将获得一个代表文档中所有元素的NodeList对象
- Element类也定义getElementsByTagName()方法,其原理和Document版本的一样,但是它只选取调用该方法的元素的后代元素。因此,要查找文档中第一个<p>元素里面的所有<span>元素,代码如下:
var firstpara=document.getElementsByTagName("p")[0];
var firstParaSpans=firstpara.getElementsByTagName("span");
- HTMLDocument类定义一些快捷属性来访问各种各样的节点。例如,images、forms和links等属性指向行为类似只读数组的<img>、<form>和<a>(但只包含那些有href属性的<a>标签)元素集合。
- HTMLDocument也定义embeds和plugins属性,它们是同义词,都是HTMLCollection类型的<embed>元素的集合。
- scripts在HTML5中是标准属性,它是HTMLCollection类型的<script>元素的集合
- document.body是一个HTML文档的<body>元素,document.head是<head>元素。
- Document类的documentElement属性指代文档的根元素。在HTML文档中,它总是指代<html>元素。
2.4 用CSS类名选取元素
在JavaScript中class是保留字,所以客户端JavaScript使用className属性来保存HTML的class属性值。
HTML定义了getElementsByClassName()方法,它基于其class属性值中的标识符来选取成组的文档元素。
在HTML文档和HTML元素上都可以调用getElementsByClassName(),它的返回值是一个实时的NodeList对象,包含文档或元素所有匹配的后代节点。
//查找其class属性值中包含"warning"的所有元素
var warnings=document.getElementsByClassName("warning");
//查找以"log"命名并且有"error"和"fatal"类的元素的所有后代
var log=document.getElementById("log");
var fatal=log.getElementsByClassName("fatal error");
2.5 用CSS选择器选取元素
CSS样式表有一种非常强大的语法,那就是选择器,它用来描述文档中的若干或多组元素。
#nav //id="nav"的元素
div //所有<div>元素
.warning //所有在class属性值中包含了"warning"的元素
// 元素可以基于属性值来选取
p[lang="fr"] //所有使用法语的段落,如:<p lang="fr">
*[name="x"] //所有包含name="x"属性的元素
// 基本的选择器可以组合使用:
span.fatal.error //其class中包含"fatal"和"error"的所有<span>元素
span[lang="fr"].warning //所有使用法语的且其class中包含"warning"的<span>元素
// 选择器可以指定文档结构:
#log span //id="log"元素的后代元素中的所有<span>元素
#log > span //id="log"元素的子元素中的所有<span>元素
body > h1:first-child // <body>的子元素中的第一个<h1>元素
获取匹配一个给定选择器的元素的Document方法querySelectorAll(),它接受包含一个CSS选择器的字符串参数,返回一个表示文档中匹配选择器的所有元素的NodeList对象
querySelector()方法与querySelectorAll()的工作原理类似,但它只是返回第一个匹配的元素(以文档顺序)或者如果没有匹配的元素就返回null。
2.6 document.all
document.all集合来表示所有文档中的元素(除了Text节点)
3. 文档结构和遍历
一旦从文档中选取了一个元素,有时需要查找文档中与之在结构上相关的部分(父亲、兄弟和子女)。
3.1 文档作为节点树(Node类)
Document对象、它的Element对象和文档中表示文本的Text对象都是Node对象。
Node定义了以下重要的属性:
parentNode该节点的父节点,或者针对类似Document对象应该是null,因为它没有父节点childNodes只读的类数组对象(NodeList对象),它是该节点的子节点的实时表示。firstChild、lastChild该节点的子节点中的第一个和最后一个,如果该节点没有子节点则为null。nextSibling、previoursSibling该节点的兄弟节点中的前一个和下一个。具有相同父节点的两个节点为兄弟节点。节点的顺序反映了它们在文档中出现的顺序。这两个属性将节点之间以双向链表的形式连接起来。nodeType该节点的类型。9代表Document节点,1代表Element节点,3代表Text节点,8代表Comment节点,11代表DocumentFragment节点。nodeValueText节点或Comment节点的文本内容。nodeName元素的标签名,以大写形式表示。
使用这些Node属性,可以用以下类似的表达式得到文档的第一个子节点下面的第二个子节点的引用:
document.childNodes[0].childNodes[1]
document.firstChild.firstChild.nextSibling
3.2 文档作为元素树(Element类)
可以将文档看做是Element对象树,忽略部分文档:Text和Comment节点。
- Element对象的
children属性。类似ChildNodes,它也是一个NodeList对象 firstElementChild,lastElementChild,类似firstChild和lastChild,但只代表子Element。nextElementSibling,previousElementSibling类似nextSibling和previousSibling,但只代表兄弟Element。childElementCount子元素的数量。返回的值和children.length值相等
类似Element和HTMLDocument等类型都像String和Array一样是类。它们不是构造函数,但它们有原型对象
4. HTML元素属性
HTML元素由一个标签和一组称为属性(attribute)的名/值对组成。
4.1 HTML属性作为Element属性
- 表示HTML文档元素的HTMLElement对象定义了读/写属性,它们映射了元素的HTML属性。
- HTMLElement定义了通用的HTTP属性(如id、标题lang和dir)的属性,以及事件处理程序属性(如onclick)。
- 特定的Element子类型为其元素定义了特定的属性。<img>元素的HTMLElement对象的src属性
var image=document.getElementById("myimage");
var imgurl=image.src;//src属性是图片的URL
image.id==="myimage"//判定要查找图片的id
var f=document.forms[0];//文档中第一个<form>
f.action="http://www.example.com/submit.php";//设置提交至的URL
f.method="POST";//HTTP请求类型
- HTML属性名不区分大小写,但JavaScript属性名则大小写敏感。从HTML属性名转换到JavaScript属性名应该采用小写。
- 但是,如果属性名包含不止一个单词,则将除了第一个单词以外的单词的首字母大写,例如:defaultChecked和tabIndex。
- 有些HTML属性名在JavaScript中是保留字。对于这些属性,一般的规则是为属性名加前缀"html"。例如,HTML的for属性(<lable>元素)在JavaScript中变为
htmlFor属性。 - "class"在JavaScript中是保留字,它是HTML非常重要的class属性,是上面规则的一个例外:在JavaScript代码中它变为
className。
- HTML属性的值通常是字符串。
- 任何HTML元素的style属性值是CSSStyleDeclaration对象,而不是字符串。
- 事件处理程序属性值总是为Function对象(或null)。
4.2 获取和设置非标准的HTML属性
- Element类型还定义了getAttribute()和setAttribute()方法来查询和设置非标准的HTML属性
- Element类型还定义了两个相关的方法,hasAttribute()和removeAttribute(),它们用来检测命名属性是否存在和完全删除属性。
4.3 HTML元素数据集属性(dataset)
在HTML5文档中,任意以"data-"为前缀的小写的属性名字都是合法的。这些“数据集属性”将不会对其元素的表现产生影响
HTML5还在Element对象上定义了dataset属性。该属性指代一个对象,它的各个属性对应于去掉前缀的data-属性。因此dataset.x应该保存data-x属性的值。带连字符的属性对应于驼峰命名法属性名:data-jquery-test属性就变成dataset.jqueryTest属性。
注意,dataset属性是元素的data-属性的实时、双向接口。设置或删除dataset的一个属性就等同于设置或移除对应元素的data-属性。
4.4 Node节点的attributes属性
- 针对非Element对象的任何节点,该属性为null。
- 对于Element对象,attributes属性是只读的类数组对象,它代表元素的所有属性。
5、HTML标签元素的内容
5.1 元素内的HTML内容
- innerHTML
- 读取Element的innerHTML属性作为字符串标记返回那个元素的内容(包括HTML标签)。
- 在元素上设置该属性调用了Web浏览器的解析器,用新字符串内容的解析展现形式替换元素当前内容。
- Web浏览器很擅长解析HTML,通常设置innerHTML效率非常高
- outerHTML
- 当查询outerHTML时,返回的HTML或XML标记的字符串包含被查询元素的开头和结尾标签。
- 当设置元素的outerHTML时,元素本身被新的内容所替换。
3. insertAdjacentHTML()方法
- 它将任意的HTML标记字符串插入到指定的元素“相邻”的位置。
- 标记是该方法的第二个参数,并且“相邻”的精确含义依赖于第一个参数的值。
- 第一个参数为具有以下值之一的字符串:"beforebegin"、"afterbegin"、"beforeend"和"afterend"。
5.2 元素的纯文本内容innerText
查询纯文本形式的元素内容,或者在文档中插入纯文本,可以用Node的textContent属性来实现:
var para=document.getElementsByTagName("p")[0];//文档中第一个<p>
var text=para.textContent; //文本是"This is a simple document."
para.textContent="Hello World!"; //修改段落内容
- textContent和innerText属性非常相似,通常可以互相替换使用。
- textContent属性就是将指定元素的所有后代Text节点简单地串联在一起。
- innerText和textContent有一些不同。innerText不返回<script>元素的内容。它忽略多余的空白,并试图保留表格格式。
5.3 元素内容是Text节点
当考虑元素的内容时,通常感兴趣的是它的Text节点。
nodeValue属性可以读/写,设置它可以改变Text节点所显示的内容
6 创建、插入、删除节点
Document类型定义了创建Element和Text对象的方法,Node类型定义了在节点树中插入、删除和替换的方法。
//从指定的URL,异步加载和执行脚本
function loadasync(url){
var head=document.getElementsByTagName("head")[0];//查找文档的<head>标签
var s=document.createElement("script");//创建一个<script>元素
s.src=url;//设置它的src属性值
head.appendChild(s);//将该<script>插入到head中
}
6.1 创建节点createElement()
创建新的Element节点可以使用Document对象的createElement()方法。给方法传递元素的标签名:对HTML文档来说该名字不区分大小写
- 创建Text节点 createTextNode()
- 创建注释节点 createComment()
- createDocumentFragment()方法
- 另一种创建新文档节点的方法是复制已存在的节点。每个节点有一个cloneNode()方法来返回该节点的一个全新副本。给方法传递参数true也能够递归地复制所有的后代节点,或传递参数false只是执行一个浅复制。
6.2 插入节点 appendChild()
一旦有了一个新节点,就可以用Node的方法appendChild()或insertBefore()将它插入到文档中。
appendChild('要插入的节点')是在需要插入的目标Element的父节点上调用的,它插入指定的目标节点使其成为调用节点的最后一个子节点。
- insertBefore()接受两个参数。第一个参数就是待插入的节点,第二个参数是已存在的节点,新节点将插入该节点的前面。
- 该方法应该是在新节点的父节点上调用,方法的第二个参数必须是该父节点的子节点。
- 如果传递null作为第二个参数,insertBefore()的行为类似appendChild(),它将节点插入在最后。
6.3 删除、替换节点 removeChild()
removeChild()方法是从文档树中删除一个节点。在父节点上调用该方法,并将需要删除的子节点作为方法参数传递给它
// 在文档中删除n节点
n.parentNode.removeChild(n);
replaceChild()方法删除一个子节点并用一个新的节点取而代之。在父节点上调用该方法,第一个参数是新节点,第二个参数是需要代替的节点。
6.4 DocumentFragment
DocumentFragment是一种特殊的Node,它作为其他节点的一个临时的容器。
DocumentFragment的特殊之处在于它使得一组节点被当做一个节点看待:如果给appendChild()、insertBefore()或replaceChild()传递一个DocumentFragment,其实是将该文档片段的所有子节点插入到文档中,而非片段本身
var frag=document.createDocumentFragment();
7.例子-生成目录表
(function() {
//匿名函数定义了一个局部作用域
//查找TOC容器元素
//如果不存在,则在文档开头处创建一个
var toc = document.getElementById("TOC");
if (!toc) {
toc = document.createElement("div");
toc.id = "TOC";
document.body.insertBefore(toc, document.body.firstChild);
}
//查找所有的标题元素
var headings;
if (document.querySelectorAll)
//我们是否能用这个简单的方法?
headings = document.querySelectorAll("h1,h2,h3,h4,h5,h6");
//否则,查找方法稍微麻烦一些
else headings = findHeadings(document.body, []);
//递归遍历document的body,查找标题元素
function findHeadings(root, sects) {
for (var c = root.firstChild; c != null; c = c.nextSibling) {
if (c.nodeType !== 1) continue;
if (c.tagName.length == 2 && c.tagName.charAt(0) == "H") sects.push(c);
else findHeadings(c, sects);
}
return sects;
}
//初始化一个数组来保持跟踪章节号
var sectionNumbers = [0, 0, 0, 0, 0, 0]; //现在,循环已找到的标题元素
for (var h = 0; h < headings.length; h++) {
var heading = headings[h]; //跳过在TOC容器中的标题元素
if (heading.parentNode == toc) continue; //判定标题的级别
var level = parseInt(heading.tagName.charAt(1));
if (isNaN(level) || level < 1 || level > 6) continue;
//对于该标题级别增加sectionNumbers对应的数字
//重置所有标题比它级别低的数字为零
sectionNumbers[level - 1]++;
for (var i = level; i < 6; i++) sectionNumbers[i] = 0;
//现在,将所有标题级别的章节号组合产生一个章节号,如2.3.1
var sectionNumber = sectionNumbers.slice(0, level).join("."); //为标题级别增加章节号
//把数字放在<span>中,使得其可以用样式修饰
var span = document.createElement("span");
span.className = "TOCSectNum";
span.innerHTML = sectionNumber;
heading.insertBefore(span, heading.firstChild);
//用命名的锚点将标题包起来,以便为它增加链接
var anchor = document.createElement("a");
anchor.name = "TOC" + sectionNumber;
heading.parentNode.insertBefore(anchor, heading);
anchor.appendChild(heading);
//现在为该节创建一个链接
var link = document.createElement("a");
link.href = "#TOC" + sectionNumber; //链接的目标地址
link.innerHTML = heading.innerHTML; //链接文本与实际标题一致
//将链接放在一个div中,div用基于级别名字的样式修饰
var entry = document.createElement("div");
entry.className = "TOCEntry TOCLevel" + level;
entry.appendChild(link); //该div添加到TOC容器中
toc.appendChild(entry);
}
})();
<h1>标题h1</h1>
<h2>标题h2</h2>
<h3>标题h3</h3>
<h4>标题h4</h4>
<h5>标题h5</h5>
8. 文档元素的位置和滚动
8.1 文档坐标和窗口坐标
- 元素的位置是以像素来度量的,向右代表X坐标的增加,向下代表Y坐标的增加。
- 但是,有两个不同的点作为坐标系的原点:元素的X和Y坐标可以相对于文档的左上角或者相对于在其中显示文档的视口的左上角。
- 在顶级窗口和标签页中,“视口”只是实际显示文档内容的浏览器的一部分:它不包括浏览器“外壳”(如菜单、工具条和标签页)。
- 针对框架页中显示的文档,视口是定义了框架页的<iframe>元素。
- 无论在何种情况下,当讨论元素的位置时,必须弄清楚所使用的坐标是文档坐标还是视口坐标。
- (注意,视口坐标有时也叫做窗口坐标。)
如果文档比视口要小,或者说它还未出现滚动,则文档的左上角就是视口的左上角,文档和视口坐标系统是同一个。但是,一般来说,要在两种坐标系之间互相转换,必须加上或减去滚动的偏移量(scrol l offset) 文档坐标比视口坐标更加基础,并且在用户滚动时它们不会发生变化。
为了在坐标系之间互相转换,我们需要判定浏览器窗口的滚动条的位置。Window对象的pageXOffset和pageYOffset属性在所有的浏览器中提供这些值
也可以通过scrollLeft和scrollTop属性来获得滚动条的位置。
8.2 查询元素的尺寸和位置getBoundingClientRect()
getBoundingClientRect()方法,它不需要参数,返回一个有left、right、top和bottom属性的对象。
8.3 判断元素在某点elementFromPoint()
Document对象的elementFromPoint()方法来判定在视口中的指定位置上有什么元素。传递X和Y坐标(使用视口坐标而非文档坐标),该方法返回在指定位置的一个元素。
8.4 滚动
- Window对象的scrollTo()方法(和其同义词scroll())接受一个点的X和Y坐标(文档坐标),并作为滚动条的偏移量设置它们。
- Window的scrollBy()方法和scroll()和scrollTo()类似,但是它的参数是相对的,并在当前滚动条的偏移量上增加。
//每200毫秒向下滚动10像素。注意,它无法关闭
setInterval(function(){scrollBy(0,10)},200);
8.5 offset\client\scroll属性
每个HTML元素都有以下这些属性:
- 任何HTML元素的只读属性
offsetWidth和offsetHeight以CSS像素返回它的屏幕尺寸。返回的尺寸包含元素的边框和内边距,除去了外边距。 - 所有HTML元素拥有
offsetLeft和offsetTop属性来返回元素的X和Y坐标。对于很多元素,这些值是文档坐标,并直接指定元素的位置。但对于已定位元素的后代元素和一些其他元素(如表格单元),这些属性返回的坐标是相对于祖先元素的而非文档。 - offsetParent属性指定这些属性所相对的父元素。如果offsetParent为null,这些属性都是文档坐标
clientWidth和clientHeight类似offsetWidth和offsetHeight,不同的是它们不包含边框大小,只包含内容和它的内边距。同时,如果浏览器在内边距和边框之间添加了滚动条,clientWidth和clientHeight在其返回值中也不包含滚动条。注意,对于类似<i>和<span>这些内联元素,clientWidth和clientHeight总是返回0。- clientLeft和clientTop属性没什么用:它们返回元素的内边距的外边缘和它的边框的外边缘之间的水平距离和垂直距离,通常这些值就等于左边和上边的边框宽度。但是如果元素有滚动条,并且浏览器将这些滚动条放置在左侧或顶部(可这不太常见),clientLeft和clientTop也就包含了滚动条的宽度。对于内联元素,clientLeft和clientTop总是为0。
HTML元素的实际内容有可能比分配用来容纳内容的盒子更大,因此单个元素可能有滚动条。内容区域是视口,就像浏览器的窗口,当实际内容比视口更大时,需要把元素的滚动条位置考虑进去
scrollWidth和scrollHeight是元素的内容区域加上它的内边距再加上任何溢出内容的尺寸。当内容正好和内容区域匹配而没有溢出时,这些属性与clientWidth和clientHeight是相等的。但当溢出时,它们就包含溢出的内容,返回值比clientWidth和clientHeight要大。scrollLeft和scrollTop指定元素的滚动条的位置。scrollLeft和scrollTop是可写的属性,通过设置它们来让元素中的内容滚动
9 HTML表单
HTML表单元素可以追溯到Web的最开始,比JavaScript本身更早。
9.1 选取表单元素
var fields=document.getElementById("address").getElementsByTagName("input");
//id为"shipping"的表单中所有的单选按钮
document.querySelectorAll('#shipping input[type="radio"]');
//id为"shipping"的表单中所有名字为"method"的单选按钮
document.querySelectorAll('#shipping input[type="radio"][name="method"]');
9.2 表单元素的属性
- type 标识表单元素类型的只读的字符串。针对用<input>标签定义的表单元素而言,就是其type属性的值。
- form 对包含元素的Form对象的只读引用,或者如果元素没有包含在一个<form>元素中则其值为null。
- name 只读的字符串,由HTML属性name指定
- value 可读/写的字符串,指定了表单元素包含或代表的“值”。它就是当提交表单时发送到Web服务器的字符串
9.3 表单元素的事件处理程序
- 每个Form元素都有一个onsubmit事件处理程序来侦测表单提交,还有一个onreset事件处理程序来侦测表单重置。
- 注意,onsubmit事件处理程序只能通过单击“提交”按钮来触发。直接调用表单的submit()方法不触发onsubmit事件处理程序。
<form onreset="return confirm('Really erase ALL input and start over?')">
<button type="reset">Clear and Start Over</button>
</form>
- 当用户与表单元素交互时它们往往会触发click或change事件,通过定义onclick或onchange事件处理程序可以处理这些事件。
- 表单元素在收到键盘的焦点时也会触发focus事件,失去焦点时会触发blur事件。
在<form>元素中的元素都有一个form属性引用了该包含的表单,并且在事件处理程序代码中关键字this是触发该事件的文档元素的一个引用,可以使用this.form来得到Form对象的引用。更进一步,这意味着某个表单元素的事件处理程序能够通过this.form.x得到该表单中以x命名的元素
9.4 按钮
- 按钮是一种视觉上明确让用户触发某种脚本动作的方法。
- 按钮元素本身没有默认的行为,除非它有onclick事件处理程序,否则它并没有什么用处。
- 以<input>元素定义的按钮会将value属性值以纯文本显示。以<button>元素定义的按钮会将元素的一切内容显示出来。
<input type="button" name="my-input" value="My-button" /> // value值是按钮显示内容
<button type="reset">Clear and Start Over</button>
9.5 单选和复选
- 复选框和单选元素是有两种视觉状态的按钮:选中或未选中。通过对其单击用户可以改变它的开关状态。
- 单选元素为整组有相关性的元素而设计的,组内所有按钮的HTML属性name的值都相同。
- 单选和复选框元素都定义了checked属性。该属性是可读/写的布尔值,它指定了元素当前是否选中。defaultChecked属性也是布尔值,它是HTML属性checked的值;它指定了元素在第一次加载页面时是否选中。
- 单选和复选框元素本身不显示任何文本,它们通常和相邻的HTML文本一起显示(或与<label>元素相关联)
9.6 输入框
用户可以输入单行简短的文本字符串。value属性表示用户输入的文本,通过设置该属性值可以显式地指定应该在输入域中显示的文本。placeholder属性指定了用户输入前在输入域中显示的提示信息
Arrival Date:<input type="text"name="arrival"placeholder="yyyy-mm-dd">
- Textarea元素类似文本输入域元素,不同的是它允许用户输入(和显示)多行文本。Textarea元素用<textarea>标签来创建
- <input type="password">元素在用户输入时显示为星号,它修改了输入的文本。只能防止眼睛窥视,但在提交表单时输入未经任何加密
- <input type="file">元素将用户输入待上传到Web服务器的文件的名称。它由一个输入框和一个单击打开文件选择对话框的按钮所组成。该文件选取元素拥有onchange事件处理程序,就像普通的输入域一样。但不同的是它的value属性是只读的。
可以定义onkeypress、onkeydown和onkeyup事件处理程序
9.7 下拉项
Select元素表示用户可以做出选择的一组选项(用Option元素表示)。浏览器通常将其渲染为下拉菜单的形式.
- 如果<select>元素有multiple属性,也就是Select对象的type属性值为"select-multiple",那就允许用户选取多个选项。否则,如果没有多选属性,那只能选取单个选项,它的type属性值为"select-one"。
- Select元素定义了options属性,它是一个包含了多个Option元素的类数组对象。
- Option对象的selected属性值判定哪些选项被选中。
- 每个Option对象有一个text属性,它指定了在Select元素中的选项所显示的纯文本字符串。设置该属性可以改变显示给用户的文本。
- value属性指定了在提交表单时发送到Web服务器的文本字符串,它也是可读/写的。
为Select元素增加一个新的选项,首先用Option()构造函数创建一个Option对象,然后将其添加到options[]属性中
//创建一个新的选项
var zaire=new Option("Zaire",//text属性
"zaire",//value属性
false,//defaultSelected属性
false);//selected属性
//通过添加到options数组中,在Select元素中显示该选项
var countries=document.querySelector("#shipping > select");//得到Select对象
countries.options[countries.options.length]=zaire;
10 文档其它属性
10.1 document属性
- cookie 允许JavaScript程序读、写HTTP cookie的特殊的属性。第20章涵盖该属性。
- domain 该属性允许当Web页面之间交互时,相同域名下互相信任的Web服务器之间协作放宽同源策略安全限制
- lastModified 包含文档修改时间的字符串。
- location 与Window对象的location属性引用同一个Location对象。
- referrer 如果有,它表示浏览器导航到当前链接的上一个文档
- title 文档的<title>和</title>标签之间的内容。
- URL 文档的URL,只读字符串而不是Location对象。该属性值与location.href的初始值相同,只是不包含Location对象的动态变化
10.2 document.write()
document.write()会将其字符串参数连接起来,然后将结果字符串插入到文档中调用它的脚本元素的位置。当脚本执行结束,浏览器解析生成的输出并显示它
- 只有在解析文档时才能使用write()方法输出HTML到当前文档中
- 如果将document.write()放在一个函数的定义中,而该函数的调用是从一个事件处理程序中发起的,产生的结果是——它会擦除当前文档和它包含的脚本!
- writeln()方法,除了在其参数的输出之后追加一个换行符以外它和write()方法完全一样
10.3 查询用户选取区域中的文本
标准的window.getSelection()方法返回一个Selection对象,它的toString()方法是Selection对象中最重要的特性,它返回选取的纯文本内容。
10.4 设置HTML元素可编辑
有两种方法来启用编辑功能。其一,设置任何标签的HTML contenteditable属性;其二,设置对应元素的JavaScript contenteditable属性;
<div id="editor" contenteditable>
Click to edit
</div>
将Document对象的designMode属性设置为字符串"on"使得整个文档可编辑。(设置为"off"将恢复为只读文档。)
所有当今的浏览器都支持contenteditable和designMode属性。