浏览器:文档,事件,接口
DOM 树
HTML 文档的主干是标签(tag)。
根据文档对象模型(DOM),每个 HTML 标签都是一个对象。嵌套的标签是闭合标签的“子标签(children)”。标签内的文本也是一个对象。
所有这些对象都可以通过 JavaScript 来访问,我们可以使用它们来修改页面。
一共有 12 种节点类型。实际上,我们通常用到的是其中的 4 种:
document
— DOM 的“入口点”。- 元素节点 — HTML 标签,树构建块。
- 文本节点 — 包含文本。
- 注释 — 有时我们可以将一些信息放入其中,它不会显示,但 JS 可以从 DOM 中读取它。
DOM 集合是只读的
DOM 集合,甚至可以说本章中列出的 所有 导航(navigation)属性都是只读的。
我们不能通过类似 childNodes[i] = ...
的操作来替换一个子节点。
修改子节点需要使用其它方法。我们将会在下一章中看到它们。
DOM 集合是实时的
除小部分例外,几乎所有的 DOM 集合都是 实时 的。换句话说,它们反映了 DOM 的当前状态。
如果我们保留一个对 elem.childNodes
的引用,然后向 DOM 中添加/移除节点,那么这些节点的更新会自动出现在集合中。
总结
HTML/XML 文档在浏览器内均被表示为 DOM 树。
- 标签(tag)成为元素节点,并形成文档结构。
- 文本(text)成为文本节点。
- ……等,HTML 中的所有东西在 DOM 中都有它的位置,甚至对注释也是如此。
遍历 DOM
DOM 让我们可以对元素和它们中的内容做任何事,但是首先我们需要获取到对应的 DOM 对象。
对 DOM 的所有操作都是以 document
对象开始。它是 DOM 的主“入口点”。从它我们可以访问任何节点。
在 DOM 的世界中,null
就意味着“不存在”
在 DOM 中,null
值就意味着“不存在”或者“没有这个节点”。
DOM 集合是只读的
DOM 集合是实时的
不要使用 for..in
来遍历集合
更多链接:表格
和 | 单元格的集合。tr.sectionRowIndex — 给定的 | |||||||
---|---|---|---|---|---|---|---|---|
和 | : td.cellIndex — 在封闭的 | |||||||
属性 | 特性 | |
---|---|---|
类型 | 任何值,标准的属性具有规范中描述的类型 | 字符串 |
名字 | 名字(name)是大小写敏感的 | 名字(name)是大小写不敏感的 |
Window 大小和滚动
窗口的 width/height
为了获取窗口(window)的宽度和高度,我们可以使用 document.documentElement
的 clientWidth/clientHeight
:
滚动:scrollTo,scrollBy,scrollIntoView
可以通过更改 scrollTop/scrollLeft
来滚动常规元素。
我们可以使用 document.documentElement.scrollTop/scrollLeft
对页面进行相同的操作(Safari 除外,而应该使用 document.body.scrollTop/Left
代替)。
方法 scrollBy(x,y)
将页面滚动至 相对于当前位置的 (x, y)
位置。例如,scrollBy(0,10)
会将页面向下滚动 10px
。
方法 scrollTo(pageX,pageY)
将页面滚动至 绝对坐标,使得可见部分的左上角具有相对于文档左上角的坐标 (pageX, pageY)
。就像设置了 scrollLeft/scrollTop
一样。
要滚动到最开始,我们可以使用 scrollTo(0,0)
。
scrollIntoView
为了完整起见,让我们再介绍一种方法:elem.scrollIntoView(top)。
对 elem.scrollIntoView(top)
的调用将滚动页面以使 elem
可见。它有一个参数:
- 如果
top=true
(默认值),页面滚动,使elem
出现在窗口顶部。元素的上边缘将与窗口顶部对齐。 - 如果
top=false
,页面滚动,使elem
出现在窗口底部。元素的底部边缘将与窗口底部对齐。
下面这个按钮会滚动页面,以使其自身定位在窗口顶部:
this.scrollIntoView()
下面这个按钮会滚动页面,以使其自身定位在窗口底部:
this.scrollIntoView(false)
总结
几何:
文档可见部分的 width/height(内容区域的 width/height):
document.documentElement.clientWidth/clientHeight
整个文档的 width/height,其中包括滚动出去的部分:
let scrollHeight = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight )
滚动:
读取当前的滚动:
window.pageYOffset/pageXOffset
。更改当前的滚动:
window.scrollTo(pageX,pageY)
— 绝对坐标,window.scrollBy(x,y)
— 相对当前位置进行滚动,elem.scrollIntoView(top)
— 滚动以使elem
可见(elem
与窗口的顶部/底部对齐)。
创建自定义事件
我们不仅可以分配事件处理程序,还可以从 JavaScript 生成事件。
自定义事件可用于创建“图形组件”。
事件构造器
内建事件类形成一个层次结构(hierarchy),类似于 DOM 元素类。根是内建的 Event 类。
我们可以像这样创建 Event
对象:
let event = new Event(type[, options]);
参数:
type —— 事件类型,可以是像这样
"click"
的字符串,或者我们自己的像这样"my-event"
的参数。options —— 具有两个可选属性的对象:
bubbles: true/false
—— 如果为true
,那么事件会冒泡。cancelable: true/false
—— 如果为true
,那么“默认行为”就会被阻止。稍后我们会看到对于自定义事件,它意味着什么。
默认情况下,以上两者都为 false:
{bubbles: false, cancelable: false}
。
dispatchEvent
事件对象被创建后,我们应该使用 elem.dispatchEvent(event)
调用在元素上“运行”它。
然后,处理程序会对它做出反应,就好像它是一个常规的浏览器事件一样。如果事件是用 bubbles
标志创建的,那么它会冒泡。
表单属性和方法
表单(form)以及例如 <input>
的控件(control)元素有许多特殊的属性和事件。
导航:表单和元素
文档中的表单是特殊集合 document.forms
的成员。
这就是所谓的“命名的集合”:既是被命名了的,也是有序的。我们既可以使用名字,也可以使用在文档中的编号来获取表单。
document.forms.my - name="my" 的表单
document.forms[0] - 文档中的第一个表单
当我们有了一个表单时,其中的任何元素都可以通过命名的集合 form.elements
来获取到。
反向引用:element.form
对于任何元素,其对应的表单都可以通过 element.form
访问到。因此,表单引用了所有元素,元素也引用了表单。
这是一张示意图:
表单元素
让我们来谈谈表单控件。
input 和 textarea
我们可以通过 input.value
(字符串)或 input.checked
(布尔值)来访问复选框(checkbox)中的它们的 value
。