摘要:方法接受一个布尔值参数,表示是否执行深复制方法不会复制添加到节点中的属性,例如事件处理程序等。由于跨域安全限制,来自不同子域的页面无法通过通信。这三个集合都是动态的换句话说,每当文档结构发生变化时,它们都会得到更新。
第十章 DOM
1001、每一段标记都可以通过树中的一个节点来表示:HTML 元素通过元素节点表示,特性(attribute)通过特性节点表示,文档类型通过文档类型节点表示,而注释则通过注释节点表示。总共有 12 种节点类型,这些类型都继承自一个基类型
1002、JavaScript 中的所有节点类型都继承自 Node 类型,因此所有节点类型都共享着相同的基本属性和方法
1003、所有节点都有的最后一个属性是 ownerDocument ,该属性指向表示整个文档的文档节点。这种关系表示的是任何节点都属于它所在的文档,任何节点都不能同时存在于两个或更多个文档中。通过这个属性,我们可以不必在节点层次中通过层层回溯到达顶端,而是可以直接访问文档节点
1004、如果需要把节点放在 childNodes 列表中某个特定的位置上,而不是放在末尾,那么可以使用insertBefore() 方法。这个方法接受两个参数:要插入的节点和作为参照的节点。插入节点后,被插入的节点会变成参照节点的前一个同胞节点( previousSibling ),同时被方法返回。如果参照节点是null ,则 insertBefore() 与 appendChild() 执行相同的操作
1005、 replaceChild() 方法接受的两个参数是:要插入的节点和要替换的节点。要替换的节点将由这个方法返回并从文档树中被移除,同时由要插入的节点占据其位置
1006、如果只想移除而非替换节点,可以使用 removeChild() 方法。这个方法接受一个参数,即要移除的节点。被移除的节点将成为方法的返回值
1007、要使用这几个方法必须先取得父节点(使用 parentNode 属性)。另外,并不是所有类型的节点都有子节点,如果在不支持子节点的节点上调用了这些方法,将会导致错误发生
1008、 cloneNode() ,用于创建调用这个方法的节点的一个完全相同的副本。 cloneNode() 方法接受一个布尔值参数,表示是否执行深复制
1009、cloneNode() 方法不会复制添加到 DOM 节点中的 JavaScript 属性,例如事件处理程序等。这个方法只复制特性、(在明确指定的情况下也复制)子节点,其他一切都不会复制。IE 在此存在一个 bug,即它会复制事件处理程序,所以我们建议在复制之前最好先移除事件处理程序
1010、最后一个方法是 normalize() ,这个方法唯一的作用就是处理文档树中的文本节点。由于解析器的实现或 DOM 操作等原因,可能会出现文本节点不包含文本,或者接连出现两个文本节点的情况。当在某个节点上调用这个方法时,就会在该节点的后代节点中查找上述两种情况。如果找到了空文本节点,则删除它;如果找到相邻的文本节点,则将它们合并为一个文本节点
1011、虽然 DOM 标准规定 Document 节点的子节点可以是 DocumentType 、 Element 、 ProcessingIn-struction 或 Comment ,但还有两个内置的访问其子节点的快捷方式。第一个就是 documentElement属性,该属性始终指向 HTML 页面中的 元素。另一个就是通过 childNodes 列表访问文档元素,但通过 documentElement 属性则能更快捷、更直接地访问该元素
1012、所有浏览器都支持 document.documentElement 和 document.body 属性
1013、作为 HTMLDocument 的一个实例, document 对象还有一些标准的 Document 对象所没有的属性。这些属性提供了 document 对象所表现的网页的一些信息。其中第一个属性就是 title ,包含着
1014、 URL 属性中包含页面完整的 URL(即地址栏中显示的 URL), domain 属性中只包含页面的域名,而 referrer属性中则保存着链接到当前页面的那个页面的 URL。在没有来源页面的情况下, referrer 属性中可能会包含空字符串。所有这些信息都存在于请求的 HTTP 头部,只不过是通过这些属性让我们能够在JavaScrip 中访问它们而已
1015、当页面中包含来自其他子域的框架或内嵌框架时,能够设置 document.domain 就非常方便了。由于 跨 域 安 全 限 制 , 来 自 不 同 子 域 的 页 面 无 法 通 过 JavaScript 通 信 。 而 通 过 将 每 个 页 面 的document.domain 设置为相同的值,这些页面就可以互相访问对方包含的 JavaScript 对象了
1016、假设有一个页面加载自 www.wrox.com,其中包含一个内嵌框架,框架内的页面加载自 p2p.wrox.com。由于 document.domain 字符串不一样,内外两个页面之间无法相互访问对方的 JavaScript 对象。但如果将这两个页面的 document.domain 值都设置为 "wrox.com" ,它们之间就可以通信了。浏览器对 domain 属性还有一个限制,即如果域名一开始是“松散的”(loose),那么不能将它再设置为“紧绷的”(tight)。换句话说,在将 document.domain 设置为 "wrox.com" 之后,就不能再将其设置回 "p2p.wrox.com" ,否则将会导致错误
1017、HTMLCollection 对象还有一个方法,叫做 namedItem() ,使用这个方法可以通过元素的 name特性取得集合中的项。对 HTMLCollection 而言,我们可以向方括号中传入数值或字符串形式的索引值。在后台,对数值索引就会调用 item() ,而对字符串索引就会调用 namedItem()
1018、有一个 document 对象的功能已经存在很多年了,那就是将输出流写入到网页中的能力。这个能力体现在下列 4 个方法中: write() 、 writeln() 、 open() 和 close() 。其中, write() 和 writeln()方法都接受一个字符串参数,即要写入到输出流中的文本。 write() 会原样写入,而 writeln() 则会在字符串的末尾添加一个换行符( n )。在页面被加载的过程中,可以使用这两个方法向页面中动态地加入内容
1019、方法 open() 和 close() 分别用于打开和关闭网页的输出流
1020、每个元素都有一或多个特性,这些特性的用途是给出相应元素或其内容的附加信息。操作特性的DOM 方法主要有三个,分别是 getAttribute() 、 setAttribute() 和 removeAttribute()
1021、与 getAttribute() 对应的方法是 setAttribute() ,这个方法接受两个参数:要设置的特性名和值。如果特性已经存在, setAttribute() 会以指定的值替换现有的值;如果特性不存在, setAttribute()则创建该属性并设置相应的值
1022、 removeAttribute() ,这个方法用于彻底删除元素的特性。调用这个方法不仅会清除特性的值,而且也会从元素中完全删除特性
1023、使用 document.createElement() 方法可以创建新元素。这个方法只接受一个参数,即要创建元素的标签名。这个标签名在 HTML 文档中不区分大小写,而在 XML(包括 XHTML)文档中,则是区分大小写的
1024、文本节点由 Text 类型表示,包含的是可以照字面解释的纯文本内容。纯文本中可以包含转义后的HTML 字符,但不能包含 HTML 代码
1025、可以使用 document.createTextNode() 创建新文本节点,这个方法接受一个参数——要插入节点中的文本
1026、使用 document.createComment() 并为其传递注释文本也可以创建注释节点
1027、虽然不能把文档片段直接添加到文档中,但可以将它作为一个“仓库”来使用,即可以在里面保存将来可能会添加到文档中的节点。要创建文档片段,可以使用 document.createDocumentFragment() 方法
1028、文档片段继承了 Node 的所有方法,通常用于执行那些针对文档的 DOM操作。如果将文档中的节点添加到文档片段中,就会从文档树中移除该节点,也不会从浏览器中再看到该节点。添加到文档片段中的新节点同样也不属于文档树。可以通过 appendChild() 或insertBefore() 将文档片段中内容添加到文档中。在将文档片段作为参数传递给这两个方法时,实际上只会将文档片段的所有子节点添加到相应位置上;文档片段本身永远不会成为文档树的一部分
1029、Attr 对象有 3 个属性: name 、 value 和 specified 。其中, name 是特性名称(与 nodeName 的值相同), value 是特性的值(与 nodeValue 的值相同),而 specified 是一个布尔值,用以区别特性是在代码中指定的,还是默认的
1030、理解 NodeList 及其“近亲” NamedNodeMap 和 HTMLCollection ,是从整体上透彻理解 DOM 的关键所在。这三个集合都是“动态的”;换句话说,每当文档结构发生变化时,它们都会得到更新。因此,它们始终都会保存着最新、最准确的信息。从本质上说,所有 NodeList 对象都是在访问 DOM文档时实时运行的查询
1031、一般来说,应该尽量减少访问 NodeList 的次数。因为每次访问 NodeList ,都会运行一次基于文档的查询。所以,可以考虑将从 NodeList 中取得的值缓存起来
1032、querySelector() 方法接收一个 CSS 选择符,返回与该模式匹配的第一个元素,如果没有找到匹配的元素,返回 null 。
1033、querySelectorAll() 方法接收的参数与 querySelector() 方法一样,都是一个 CSS 选择符,但返回的是所有匹配的元素而不仅仅是一个元素。这个方法返回的是一个 NodeList 的实例
1034、如果传入了浏览器不支持的选择符或者选择符中有语法错误,querySelectorAll() 会抛出错误
1035、Selectors API Level 2 规范为 Element 类型新增了一个方法 matchesSelector() 。这个方法接收一个参数,即 CSS 选择符,如果调用元素与该选择符匹配,返回 true ;否则,返回 false
1036、对于元素间的空格,IE9及之前版本不会返回文本节点,而其他所有浏览器都会返回文本节点
1037、支持 getElementsByClassName() 方法的浏览器有 IE 9+、Firefox 3+、Safari 3.1+、Chrome 和Opera 9.5+
1038、新增了 document.hasFocus() 方法,这个方法用于确定文档是否获得了焦点
1039、使用 document.readyState 的最恰当方式,就是通过它来实现一个指示文档已经加载完成的指示器。支持 readyState 属性的浏览器有 IE4+、Firefox 3.6+、Safari、Chrome和 Opera 9+
1040、自从 IE6 开始区分渲染页面的模式是标准的还是混杂的,检测页面的兼容模式就成为浏览器的必要功能。IE 为此给 document 添加了一个名为 compatMode 的属性,这个属性就是为了告诉开发人员浏览器采用了哪种渲染模式。就像下面例子中所展示的那样,在标准模式下, document.compatMode 的值等于 "CSS1Compat" ,而在混杂模式下, document.compatMode 的值等于 "BackCompat"。
1041、HTML5规定可以为元素添加非标准的属性,但要添加前缀 data- ,目的是为元素提供与渲染无关的信息,或者提供语义信息。这些属性可以任意添加、随便命名,只要以 data- 开头即可
1042、在读模式下, innerHTML 属性返回与调用元素的所有子节点(包括元素、注释和文本节点)对应的 HTML 标记。在写模式下, innerHTML 会根据指定的值创建新的 DOM树,然后用这个 DOM 树完全替换调用元素原先的所有子节点
1043、在写模式下, innerHTML 的值会被解析为 DOM 子树,替换调用元素原来的所有子节点。因为它的值被认为是 HTML,所以其中的所有标签都会按照浏览器处理 HTML 的标准方式转换为元素(同样,这里的转换结果也因浏览器而异)。如果设置的值仅是文本而没有 HTML 标签,那么结果就是设置纯文本
1044、 innerHTML 字符串一开始(而且整个)就是一个“无作用域的元素”,所以这个字符串会变成空字符串
1045、不支持 innerHTML 的元素有: