2023 年 11 月学习日志

94 阅读5分钟

往期

2023 年 10 月(下)学习日志

11-30 Document 类型

URL、domain 和 referrer

文档信息 document 还有 3 个属性是 URL、domain 和 referrer。

其中,URL 包含当前页面的完整 URL(地址栏中的 URL),domain 包含页面的域名,而 referrer 包含链接到当前页面的那个页面的 URL。 如果当前页面没有来源,则 referrer 属性包含空字符串。所有这些信息都可以在请求的 HTTP 头部信息中获取,只是在 JavaScript 中通过这几个属性暴露出来而已,如下面的例子所示:

let url = document.URL;
// 取得域名
let domain = document.domain;
// 取得来源
let referrer = document.referrer;

其中 domain 属性是可以设置的,但是也是有限制的

  • 一旦收紧不能放松
    // 页面来自 p2p.wrox.com
    document.domain = "wrox.com"; // 放松,成功
    document.domain = "p2p.wrox.com"; // 收紧,错误!
    
  • 只能设置包含的关系如果 URL 包含子域名如 p2p.wrox.com,则可以将 domain 设置为"wrox.com"(URL 包含“www”时也一样,比如 www.wrox.com ,不能给这个属性设置 URL 中不包含的值
    // 页面来自 p2p.wrox.com
    document.domain = "wrox.com"; // 成功
    document.domain = "nczonline.net"; // 出错!
    

定位元素

  • 如果页面中存在多个具有相同 ID 的元素,则 getElementById()返回在文档中出现的第一个元素
  • HTMLCollection 对象还有一个额外的方法 namedItem(),可通过标签的 name 属性取得某一项的引用,这样,HTMLCollection 就提供了除索引之外的另一种获取列表项的方式,从而为取得元素提供了便利。

DOM 测试兼容性

  • 如果浏览器支持指定的特性和版本,则 hasFeature() 方法返回 true
let hasXmlDom = document.implementation.hasFeature("XML", "1.0");

由于实现不一致,因此 hasFeature()的返回值并不可靠。


11-06 DOM

DOM 又叫文档对象模型,是 HTML 和 XML 文档的编程接口

DOM 现在是真正跨平台、语言无关的表示和操作网页的方式

节点层级

HTML 中的每段标记都可以表示为这个树形结构中的一个节点。元素节点表示 HTML 元素,属性节点表示属性,文档类型节点表示文档类型,注释节点表示注释。DOM 中总共有 12 种节点类型,这些类型都继承一种基本类型。

Node 类型

DOM Level 1 描述了名为 Node 的接口,这个接口是所有 DOM 节点类型都必须实现的。Node 接口在 JavaScript 中被实现为 Node 类型,在除 IE 之外的所有浏览器中都可以直接访问这个类型。在 JavaScript中,所有节点类型都继承 Node 类型,因此所有类型都共享相同的基本属性和方法。

每个节点都有 nodeType 属性,表示该节点的类型。节点类型由定义在 Node 类型上的 12 个数值常量表示:

image.png

image.png

document 节点表示每个文档的根节点。在这里,根节点的唯一子节点是<html>元素,我们称之为文档元素(documentElement)。文档元素是文档最外层的元素,所有其他元素都存在于这个元素之内。每个文档只能有一个文档元素。在 HTML 页面中,文档元素始终是<html>元素。在 XML 文档中,则没有这样预定义的元素,任何元素都可能成为文档元素

父节点和它的第一个及最后一个子节点也有专门属性:firstChildlastChild 分别指向childNodes 中的第一和最后一个子节点。someNode.firstChild 的值始终等于 someNode.childNodes[0],而 someNode.lastChild 的值始终等于 someNode.childNodes[someNode.childNodes.length-1]

如果只有一个子节点,则 firstChild 和 lastChild 指向同一个节点。如果没有子节点,则 firstChild 和 lastChild 都是 null。上述这些节点之间的关系为在文档树的节点之间导航提供了方便。图 14-2 形象地展示了这些关系。

节点类型可通过与这些常量比较来确定,比如:

if (someNode.nodeType == Node.ELEMENT_NODE){
  alert("Node is an element.");
}

1. nodeName 与 nodeValue

nodeName 与 nodeValue 保存着有关节点的信息。这两个属性的值完全取决于节点类型。

2. 节点关系

文档中的所有节点都与其他节点有关系。这些关系可以形容为家族关系,相当于把文档树比作家谱。

每个节点都有一个 childNodes 属性,其中包含一个 NodeList 的实例。NodeList 是一个类数组对象,用于存储可以按位置存取的有序节点。

注意,NodeList 并不是 Array 的实例,但可以使用中括号访问它的值,而且它也有 length 属性。NodeList 对象独特的地方在于,它其实是一个对 DOM 结构的查询,因此 DOM 结构的变化会自动地在 NodeList 中反映出来。

我们通常说 NodeList 是实时的活动对象,而不是第一次访问时所获得内容的快照。

image.png

3. 操纵节点(4种)

  • appendChild():用于在 childNodes 列表末尾添加节点。添加新节点会更新相关的关系指针,包括父节点和之前的最后一个子节点。appendChild()方法返回新添加的节点
  • insertBefore():如果想把节点放到 childNodes 中的特定位置而不是末尾,则可以使用 insertBefore()方法。这个方法接收两个参数:要插入的节点和参照节点。调用这个方法后,要插入的节点会变成参照节点的前一个同胞节点,并被返回。如果参照节点是 null,则 insertBefore()appendChild()效果相同。
  • replaceChild():方法接收两个参数:要插入的节点和要替换的节点,要替换的节点会被返回并从文档 树中完全移除,要插入的节点会取而代之。 (appendChild() insertBefore() 在插入节点时不会删除任何已有节点) - removeChild():要移除节点而不是替换节点,可以使用 removeChild()方法。这个方法接收一个参数,即要移除的节点。被移除的节点会被返回

4. 其他方法(节点共享)

  • cloneNode():cloneNode()方法接收一个布尔值参数,表示是否深复制。在传入 true 参数时,会进行深复制,即复制节点及其整个子 DOM 树。如果传入 false,则只会复制调用该方法的节点。