属性的操作
HTML
元素包括标签名和若干个键值对,这个键值对就称为“属性”(attribute)。
123<a id="test" href="http://www.example.com"> 链接</a>
上面代码中,a元素包括两个属性:id属性和href属性。
属性本身是一个对象(Attr对象),但是实际上,这个对象极少使用。一般都是通过元素节点对象(HTMlElement对象)来操作属性。本章介绍如何操作这些属性。
Element.attributes 属性
元素对象有一个attributes属性,返回一个类似数组的动态对象,成员是该元素标签的所有属性节点对象,属性的实时变化都会反映在这个节点对象上。其他类型的节点对象,虽然也有attributes属性,但返回的都是null,因此可以把这个属性视为元素对象独有的。
单个属性可以通过序号引用,也可以通过属性名引用。
12345// HTML 代码如下// <body bgcolor="yellow" onload="" ...
Element 节点
简介
Element节点对象对应网页的 HTML 元素。每一个 HTML
元素,在 DOM
树上都会转化成一个Element节点对象(以下简称元素节点)。
元素节点的nodeType属性都是1。
123var p = document.querySelector('p');p.nodeName // "P"p.nodeType // 1
Element对象继承了Node接口,因此Node的属性和方法在Element对象都存在。
此外,不同的 HTML
元素对应的元素节点是不一样的,浏览器使用不同的构造函数,生成不同的元素节点,比如<a>元素的构造函数是HTMLAnchorElement(),<button>是HTMLButtonElement()。因此,元素节点不是一种对象,而是许多种对象,这些对象除了继承Element对象的属性和方法,还有各自独有的属性和方法。
实例属性
元素特性的相关属性
(1)Element.id
Element.id属性返回指定元素的id属性,该属性可读写。
123// H ...
Document 节点
概述
document节点对象代表整个文档,每张网页都有自己的document对象。window.document属性就指向这个对象。只要浏览器开始载入
HTML 文档,该对象就存在了,可以直接使用。
document对象有不同的办法可以获取。
正常的网页,直接使用document或window.document。
iframe框架里面的网页,使用iframe节点的contentDocument属性。
Ajax
操作返回的文档,使用XMLHttpRequest对象的responseXML属性。
内部节点的ownerDocument属性。
document对象继承了EventTarget接口和Node接口,并且混入(mixin)了ParentNode接口。这意味着,这些接口的方法都可以在document对象上调用。除此之外,document对象还有很多自己的属性和方法。
属性
快捷方式属性
以下属性是指向文档内部的某个节点的快捷方式。
(1)document.defaultView
document.defaultView属性返回document对象所属的wi ...
ParentNode 接口,ChildNode
接口
节点对象除了继承 Node
接口以外,还拥有其他接口。ParentNode接口表示当前节点是一个父节点,提供一些处理子节点的方法。ChildNode接口表示当前节点是一个子节点,提供一些相关方法。
ParentNode 接口
如果当前节点是父节点,就会混入了(mixin)ParentNode接口。由于只有元素节点(element)、文档节点(document)和文档片段节点(documentFragment)拥有子节点,因此只有这三类节点会拥有ParentNode接口。
ParentNode.children
children属性返回一个HTMLCollection实例,成员是当前节点的所有元素子节点。该属性只读。
下面是遍历某个节点的所有元素子节点的示例。
123for (var i = 0; i < el.children.length; i++) { // ...}
注意,children属性只包括元素子节点,不包括其他类型的子节点(比如文本子节点)。如果没有元素类型的子节点,返回值HTMLCol ...
NodeList 接口,HTMLCollection
接口
节点都是单个对象,有时需要一种数据结构,能够容纳多个节点。DOM
提供两种节点集合,用于容纳多个节点:NodeList和HTMLCollection。
这两种集合都属于接口规范。许多 DOM
属性和方法,返回的结果是NodeList实例或HTMLCollection实例。主要区别是,NodeList可以包含各种类型的节点,HTMLCollection只能包含
HTML 元素节点。
NodeList 接口
概述
NodeList实例是一个类似数组的对象,它的成员是节点对象。通过以下方法可以得到NodeList实例。
Node.childNodes
document.querySelectorAll()等节点搜索方法
1document.body.childNodes instanceof NodeList // true
NodeList实例很像数组,可以使用length属性和forEach方法。但是,它不是数组,不能使用pop或push之类数组特有的方法。
123456var children = document.bo ...
Node 接口
所有 DOM 节点对象都继承了 Node 接口,拥有一些共同的属性和方法。这是
DOM 操作的基础。
属性
Node.prototype.nodeType
nodeType属性返回一个整数值,表示节点的类型。
1document.nodeType // 9
上面代码中,文档节点的类型值为9。
Node 对象定义了几个常量,对应这些类型值。
1document.nodeType === Node.DOCUMENT_NODE // true
上面代码中,文档节点的nodeType属性等于常量Node.DOCUMENT_NODE。
不同节点的nodeType属性值和对应的常量如下。
文档节点(document):9,对应常量Node.DOCUMENT_NODE
元素节点(element):1,对应常量Node.ELEMENT_NODE
属性节点(attr):2,对应常量Node.ATTRIBUTE_NODE
文本节点(text):3,对应常量Node.TEXT_NODE
文档片断节点(DocumentFragment):11,对应常量Node.DOCUMENT_FRAG ...
DOM 概述
DOM
DOM 是 JavaScript 操作网页的接口,全称为“文档对象模型”(Document
Object Model)。它的作用是将网页转为一个 JavaScript
对象,从而可以用脚本进行各种操作(比如增删内容)。
浏览器会根据 DOM 模型,将结构化文档(比如 HTML 和
XML)解析成一系列的节点,再由这些节点组成一个树状结构(DOM
Tree)。所有的节点和最终的树状结构,都有规范的对外接口。
DOM 只是一个接口规范,可以用各种语言实现。所以严格地说,DOM 不是
JavaScript 语法的一部分,但是 DOM 操作是 JavaScript 最常见的任务,离开了
DOM,JavaScript 就无法控制网页。另一方面,JavaScript 也是最常用于 DOM
操作的语言。后面介绍的就是 JavaScript 对 DOM 标准的实现和用法。
节点
DOM 的最小组成单位叫做节点(node)。文档的树形结构(DOM
树),就是由各种不同类型的节点组成。每个节点可以看作是文档树的一片叶子。
节点的类型有七种。
Document:整个文档树的顶层节点
...
Promise 对象
概述
Promise 对象是 JavaScript
的异步操作解决方案,为异步操作提供统一接口。它起到代理作用(proxy),充当异步操作与回调函数之间的中介,使得异步操作具备同步操作的接口。Promise
可以让异步操作写起来,就像在写同步操作的流程,而不必一层层地嵌套回调函数。
注意,本章只是 Promise
对象的简单介绍。为了避免与后续教程的重复,更完整的介绍请看《ES6 标准入门》的《Promise
对象》一章。
首先,Promise 是一个对象,也是一个构造函数。
12345function f1(resolve, reject) { // 异步代码...}var p1 = new Promise(f1);
上面代码中,Promise构造函数接受一个回调函数f1作为参数,f1里面是异步操作的代码。然后,返回的p1就是一个
Promise 实例。
Promise 的设计思想是,所有异步任务都返回一个 Promise 实例。Promise
实例有一个then方法,用来指定下一步的回调函数。
12var p1 = new Promis ...
定时器
JavaScript
提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInterval()这两个函数来完成。它们向任务队列添加定时任务。
setTimeout()
setTimeout函数用来指定某个函数或某段代码,在多少毫秒之后执行。它返回一个整数,表示定时器的编号,以后可以用来取消这个定时器。
1var timerId = setTimeout(func|code, delay);
上面代码中,setTimeout函数接受两个参数,第一个参数func|code是将要推迟执行的函数名或者一段代码,第二个参数delay是推迟执行的毫秒数。
123456console.log(1);setTimeout('console.log(2)',1000);console.log(3);// 1// 3// 2
上面代码会先输出1和3,然后等待1000毫秒再输出2。注意,console.log(2)必须以字符串的形式,作为setTimeout的参数。
如果推迟执行的是函数,就直接将函数名,作为setTimeout的参数。
1 ...
异步操作概述
单线程模型
单线程模型指的是,JavaScript 只在一个线程上运行。也就是说,JavaScript
同时只能执行一个任务,其他任务都必须在后面排队等待。
注意,JavaScript 只在一个线程上运行,不代表 JavaScript
引擎只有一个线程。事实上,JavaScript
引擎有多个线程,单个脚本只能在一个线程上运行(称为主线程),其他线程都是在后台配合。
JavaScript 之所以采用单线程,而不是多线程,跟历史有关系。JavaScript
从诞生起就是单线程,原因是不想让浏览器变得太复杂,因为多线程需要共享资源、且有可能修改彼此的运行结果,对于一种网页脚本语言来说,这就太复杂了。如果
JavaScript 同时有两个线程,一个线程在网页 DOM
节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?是不是还要有锁机制?所以,为了避免复杂性,JavaScript
一开始就是单线程,这已经成了这门语言的核心特征,将来也不会改变。
这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延 ...
