脚本化文档
客户端的 javascript 的存在使得静态的 HTML 文档变成了交互式的 Web 应用。每个 Window 对象有一个 document 属性引用了 Document 对象,它是一个巨大的 API 中核心对象,叫做文档对象模型(DOM),它代表操作文档的内容。
选取文档元素
DOM 定义了多种方式来选取元素:
用指定的 id 属性
document.getElementById();用指定的 name 属性
document.getElementsByName();用指定的标签名
document.getElementsByTagName();用指定的 CSS 类
document.getElementsByClassName();用 CSS 选择器
querySelector(),querySelectorAll()。
通过标签名选取元素
HTMLDocument 类定义了一些快捷属性来访问各种各样的节点。例如,images、forms 和 links 等属性指向类似只读数组的 img、form 和 a 元素集合。这些属性指代 HTMLCollection 对象,它们可以用元素的 ID 或名字来索引:
document.forms.idHTMLDocument 对象还定义了两个属性,它们指代单个元素而非元素的集合。document.body是一个 HTML 文档的 body 元素,document.head 是 head 元素。这些属性总是对定义:如果文档源代码未显示地包含 head 和 body 元素,浏览器将隐式地创建它们。Document 类的 documentElement 属性指代文档的根元素。在 HTML 文档中,它总是指代 html 元素。
节点列表和 HTML 集合
document.getElementsByName()和document.getElementsByTagName()都返回 NodeList 对象,而类似 document.images 和 document.forms 的属性为 HTMLCollection 对象。
NodeList 和 HTMLCollection 对象不是历史文档状态的一个静态快照,而通常是实时的,并且当文档变化时它们所包含的元素列表能随之改变。
通过 CSS 类选取元素
querySelectorAll()接受包含一个 CSS 选择器的字符串参数,其返回的 NodeList 对象并不是实时的:它包含在调用时刻选择器所匹配的元素。querySelector()的只返回第一个匹配的元素。这两个方法在 Element 节点中也有定义。在元素上调用是,指定的选择器仍在整个文档中进行匹配,然后过滤出结果集以便它只包含指定元素的后代元素。这意味着选择器字符串能包含元素的祖先元素而不仅仅是上述匹配元素。
文档结构和遍历
作为节点树的文档
Document 对象、它的 Element 对象和文档中表示文本的 Text(注意不仅仅是节点,纯文字也算进去了)对象都是 Node 对象。Node 定义了以下属性:
parentNode:该节点的父节点,或者针对类似Document对象应该是null。firstChild、lastChild:该节点的子节点中的第一个和最后一个,如果该节点的没有子节点则为null。nextSibling、previousSibling:该节点的兄弟节点中的前一个和下一个。nodeType:该节点的类型。9代表 Document 节点,1 代表Element节点,3 代表 Text 节点,8 代表Comment节点,11 代表DocumentFragment节点。nodeValue:Text节点或Comment节点的文本内容。nodeName:元素的标签名,以大写形式表示。
作为元素树的文档
基于元素的文档遍历 API 的第二部分是 Element 属性,后者类似 Node 对象的子属性和兄弟属性:
firstElementChild,lastElementChild:代表子Element;nextElementSibling,previousElementSibling:代表兄弟Element。ChildElementCount:子元素的数量。
属性
HTML 元素由一个标签和一组称为属性的名/值对组成。
例如,查询一张图片的 URL,可以用表示元素的 HTMLElement 对象的 src 属性:
HTML 属性名不区分大小写,但 javascript 属性名则大小写敏感。从 HTML 属性名转换到 javascript 属性名应该小写。如果属性名不止包含一个单词,则将除了第一个单词以外的单词首字母大写。
有些 HTML 属性名在 javascript 中是保留字。对于这些属性,一般规则是为属性名加前缀“html”。例如,HTML 的 for 属性在 javascript 中变为 htmlFor 属性。“class”在 javascript 中是保留字,它是 HTML 非常重要的 class 属性,是上面规则的一个例外:在 javascript 代码中它变为了 ClassName。
获取和设置非标准 HTML 属性
HTMLElement 和其子类定义了一些属性,它们对应于元素的标准 HTML 属性。Element 类型还定义了 getAttribute()和 setAttribute()方法来查询和设置非标准的 HTML 属性,也可用来查询和设置 XML 文档中元素上的属性。
Element 类型还定义了两个相关的方法,hasAttribute()和 removeAttribute(),它们用来检测命名属性是否存在和完全删除属性。
数据集属性
HTML5 还在 Element 对象上 dataset 属性。该属性指代一个对象,它的各个属性对应于去掉前缀的 data-属性。因此 dataset.x 应该保存 data-x 属性的值。带连字符的属性对应于驼峰命名法:data-jquery-test 属性就变成 dataset.jqueryTest 属性。dataset 属性是元素的 data-属性的实时、双向接口。设置或删除 dataset 的一个属性就等于同于设置或移除对应元素的 data-属性。
作为 Attr 节点的属性
Node 类型定义了 attribute 属性,attribute 对象也是实时的。它可以用数字索引访问,这意味着可以枚举元素的所有属性。并且,它也可以用属性名索引(前提是在 html 中设置过了):
Attr 的 name 和 value 属性属性返回该属性的名字和值。
元素的内容
作为 HTML 的元素内容
读取 Element 的 innerHTML 属性作为字符串标记返回那个元素的内容。在元素上设置该属性调用了 web 浏览器的解析器,用新字符串的内容的解析展现形式替换元素当前内容。
HTML5 还标准化了 outerHTML 属性。当查询 outerHTML 时,返回的 HTML 或 XML 标记的字符串包含被查询元素的开头和结尾标签。当设置元素的 outerHTML 时,元素本身被新的内容所替换。
另一个 HTNL5 标准化的特性是 insertAdjacentHTML()方法,它将任意的 HTML 标记字符串插入到指定的元素“相邻”的位置。第一个参数为具有以下值之一的字符串:beforeBegin、afterBegin、beforeEnd、afterEnd。
作为纯文本的元素内容
有时需要查询纯文本形式的元素内容,或者在文档中插入纯文本。标准方法是用 Node 的 textContent 属性来实现。textContent 属性就是将指定元素的所有 Text 节点简单地串联在一起,而且会返回 script 元素的内容。
script 元素中的文本
内联的 script 元素有一个 text 属性来获取它们的文本。浏览器不显示 script 元素的内容,并且 HTML 解析器忽略脚本中的尖括号和星号。这使得 script 元素称为应用程序用来嵌入任意文本的一个理想的地方。简单的将元素的 type 设置为某些值。就表明了脚本为不可执行的 javascript 代码。如果这样做,javascript 解释器将忽略该脚本,但该元素将仍存在于文档树,它的 text 属性还将返回数据给你。
节点创建插入删除
创建节点
创建新的节点可以用 Document 对象 createElement()方法,text 节点则使用 document 的 createTextNode 方法。例如:
每个节点有一个 cloneNode()方法来返回该节点的一个全新副本。给方法传递参数 true 也能递归地复制所有的后代节点,或者传递参数 false 只是执行一个浅复制。在除 IE 的其他浏览器中,Document 对象还定义了一个类似的方法叫 importNode()。如果传递给它另一个文档的一个节点,他将返回一个适合本文档插入的节点的副本。传入 true 作为第二个参数,该方法将递归地导入所有的后代节点。
插入节点
一旦有了一个新节点,就可以用 Node 的方法 appendChild()或 insertBefore()将它插入文档中。appendChild()是在需要插入的 Element 节点上调用的。而 insertBefore()接受两个参数,第一个参数是待插入的节点,第二个参数是已存在的节点,新节点将插入该节点的前面。该方法也是在新节点的父节点上调用,方法的第二个参数必须是该父节点的子节点。如果传递 null 作为第二个参数,insertBefore()的行为类似 appendChild(),它将节点插入在最后。
如果调用 appendChild()或 insertBefore()将已存在文档中的一个节点再次插入,那个节点自动从当前位置删除并在新的位置重新插入。
删除和替换节点
removeChild()方法是从文档树中删除一个节点。但是请小心:该方法不是在待删除的节点上调用,而是在其父节点上调用。在父节点上调用该方法,并将需要删除的子节点作为方法参数传递给它。
replaceChild()方法删除一个子节点并用一个新的节取而代之。在父节点上调用该方法,第一个参数是新节点,第二个参数是需要要代替的节点。
使用 DocumentFragment
DocumentFragment 是一种特殊的 Node,它作为其他节点的一个临时的容器。例如:
像 Document 节点一样,DocumentFragment 是独立的,而不是任何其他文件的一部分。它的 parentNode 总是为 null。但类似 Element,它可以有任意多的子节点,可以用 appendChild(),insertBefore()等方法来操作它们。
DocumentFragment 的特殊之处在于它使得一组节点被当做一个节点看待:如果给 appendChild()、insertBefore()或 replaceChild()传递一个 DocumentFragment。其实是将该文档的所有子节点插入到文档。
几何形状和滚动
文档坐标和视口坐标
两个不同的点坐标系的原点:元素的 X 和 Y 坐标可以相对文档的左上角或者相对于在其中显示文档的视口的左上角。在顶级窗口和标签页中,”视口“只是实际显示文档内容的浏览器的一部分。
查询元素的几何尺寸
getBoundingClientRext()方法用来判定一个元素的尺寸和位置。它不需要参数,返回一个由 left、right、top、bottom 属性的对象。left 和 top 属性表示元素的左上角的 X 和 Y 坐标,right 和 bottom 属性表示元素的右下角的 X 和 Y 坐标。getBoundingClientRext()返回对象还包含 width 和 height 属性,且返回的坐标包含元素的边框和内边距,但不包含元素的外边距。
如果想查询内联元素每个独立的矩形,调用 getClientRects()方法来获得一个只读的类数组对,它的每个元素类似 getBoundingClientRext()返回的矩形对象。
getBoundingClientRext()和 getClientRects()所返回的矩形对象并不是实时的。它们只是调用方法时文档视觉状态的静态快照,在用户滚动或改变浏览器窗口大小时不会改变更新它们。
判定元素在某点
Document 对象的 elementFromPoint()方法用来判定指定位置上有什么元素。通过传递 X 和 Y 坐标,该方法返回在指定位置的一个元素。该方法的意图就是返回在那个点的最里面的和最上面的元素。如果指定的点在视口以外,elementFromPoint()返回 null,即使点在转换为文档坐标后是完美有效地,返回值也是一样。
滚动
Window 对象的 scrollTop()方法(同义词 scroll())接受一个点 X 和 Y 坐标,并作为滚动条的偏移量设置它们。Window 的 scrollBy()方法和 scroll()和 scrollTo()类似,但是它的参数是相对的,并在当前滚动条的偏移量上增加。
在需要显示的 HTML 元素调用 scrollIntoView()方法(最好配好事件使用)保证元素能在视口中可见。默认情况下,它试图将元素的上边缘放在或尽量接近视口的的上边缘。如果只传递 false 作为参数,他将试图将元素的下边缘放在或尽量接近视口的下边缘。其余设置 window.location.hash 为一个命名锚点的名字后浏览器产生的行为类似。
关于元素尺寸、位置和溢出的更多信息
任何 HTML 元素的只读属性 offsetWidth 和 offsetHeight 以 CSS 像素返回它的屏幕尺寸。返回的尺寸包含元素的边框和内边距,除去了外边距。所有的 HTML 元素拥有 offsetLeft 和 offsetTop 属性来返回元素的 X 和 Y 坐标。对于很多元素,这些值是文档坐标并直接指定元素的位置。但对于已定位元素的后代元素和一些其他元素,这些属性返回的坐标是相对于祖先元素的而非文档。offsetParent 属性指定这些属性所相对的父元素。如果 offsetParent 为 null,这些属性都是文档坐标。
除了这些名字以 offset 开头的属性以外,所有的文档元素定义了其他两组属性,其名称一组以 client 开头,另一组以 scroll 开头。即,每个 HTML 元素都有以下这些属性:
clientWidth 和 clientHeight 类似 offsetWidth 和 offsetHeight,不同的是它们不包含边框大小,只包含内容和它的内边距。对于类似<i>、<code>和<span>这些内联元素,clientWidth 和 clientHeight 总是返回 0。
HTML 表单
选取表单和表单元素
在支持 querySelectorAll()的浏览器中,从一个表单中选取所有的单选按钮或有所同名的元素的代码如下:
有 name 或 id 属性的<form>元素能够通过很多方法来选取。name="address"属性的<form>可以用以下任何方法来选取:
表单和元素的属性
javascript 的 From 对象支持两个方法:submit()和 reset(),它们完成同样的目的。调用 From 对象的 submit()方法来提交表单,调用 reset()方法来重置表单元素的值。
所有表单通常都有以下属性:
type:标识表单元素类型的只读字符串。form:对包含元素的Form对象的只读引用,或者如果元素没有包含在一个<form>元素中则其值为null。name:只读的字符串,由 HTML 属性那么指定。value:可读/写的字符串,指定了表单元素包含或代表的“值”。
表单和元素的事件处理程序
每个 Form 元素都有一个 onsubmit 事件处理程序来侦测表单提交,还有一个 onrest 事件处理程序来侦测表单重置。表单提交前调用 onsubmit 程序:它通过返回 false 能够取消提交动作。注意,onsubmit 事件处理程序只能通过点击“提交”按钮来触发。直接调用表单的 submit()方法不会触发。
既然在<form>元素中的元素都有一个 form 属性引用了该包含的表单这些元素的事件处理程序总是能够通过 this.form 来得到 Form 对象的引用。更进一步,这意味着某个表单元素的事件处理程序能够通过 this.form.x 得到该表单中以 x 命名的元素。
开关按钮
单选和复选框元素都定义了 checked 属性。该属性是可读/写的布尔值,它指定了元素当前是否选中。defaultChecked 属性也是布尔值,它是 HTML 属性 checked 的值;它指定元素在第一次加载页面时是否选中。
选择框和选项元素
Select 元素能以两种不同的方式运作,这取决于它的 type 属性值是如何设置的。如果 select 元素有 nultiple 属性,也就是 Select 对象的属性值为select-multiple,那就允许用户选取多个选项。否则没有多选属性,那只能选取单个选项,它的 type 属性值为select-one。针对select-one的Select 元素,单个 selectedIndex 指定了哪个选项被选中。针对select-multiple元素,单个 selectedIndex 属性不足以表示被选中的一组选项。在这种情况下,要判定哪些选项被选中,就必须遍历 options[]数组的元素,并检测每个 Option 对象的 selected 属性值。
除了其 selected 属性,每个 Option 对象有一个 text 属性,它指定了在 Select 元素中的选项所显示的纯文本字符串。设置该属性可以改变显示给用户的文本。value 属性指定了在提交表单时发送到 Web 服务器的文本字符串,它也是可读/写的。
对于一些专用的 Select 的 API,例如new Option()等,这些 API 已经很老了,可以用标准的调用更明确地插入和移除选项元素:Document.createElement()、Node.insertBefore()、Node.removeChild()等。
其他文档特性
Document 的属性
文档定义了一些有趣的属性:
cookie:允许 javascript 程序读、写HTTP cookie的特殊的属性。domain:该属性允许当Web页面之间交互时,相同域名下互相信任的Web服务器之间协作放宽同源策略安全限制。lastModified:包含文档修改时间的字符串。location:与Window对象的location属性引用同一个Location对象。referrer:如果有,它表示浏览器导航到当前链接的上一个文档。该属性值和HTTP的Referer头信息的内容相同,只是拼写上有两个r。title:文档的title标签之间的内容。文档的
URL,只读字符串而不是Location对象。该属性值与location.href的初始值相同,只是不包含Location对象的动态变化。
查询选取的文本
标准的 window.getSelection()方法返回一个 Selection 对象,后者描述了当前选取的一系列一个或多个 Range 对象。
可编辑的内容
有两种方法来启用编辑功能。其一,设置任何标签的 HTML contenteditable 属性;其二,设置对应元素的 javascript contenteditable 属性。
为元素添加 spellcheck 属性来显式开启拼写检查,而使用spellcheck=false来显式关闭该功能。
将 Document 对象的 designMode 属性设置为字符串on使得整个文档可编辑。
浏览器定义了多项文本编辑器命令,大部分没有键盘快捷键。为了执行这些命令,应该使用 Document 对象的 execCommand()方法。可用此方法制作富文本编辑器。点击这里了解更多。
Last updated