(二)文档对象模型(DOM),你只需知道这些就够了!

官方定义——应用程序编程接口(API)

文档对象模型是用于HTML和XML文档的应用程序编程接口,它定义文档的逻辑结构,以及访问和操作文档的方式

"The Document Object Model (DOM) is an application programming interface (API) for HTML and XML documents. It defines the logical structure of documents and the way a document is accessed and manipulated." —— W3C DOM

“文档对象模型是用于HTML和XML文档的应用程序编程接口”

应用程序编程接口(Application Program Interface,简称API),就是“提供商”将一个功能的具体实现(业务逻辑)封装起来,只暴露给“客户”可供调用的编程接口。如果客户想使用某一功能,则只需调用该功能对应的编程接口,而无需关注于具体实现。打个比方,海尔生产空调,你购买空调后按照说明书操作空调就好,不需要知道空调是根据什么原理造出来的。

对于DOM而言,“提供商”指的就是实现DOM的开发者(比如,开发JavaScript引擎V8的工程师),“客户”指的就是使用DOM的开发者(比如,开发网站的前端工程师)。他们之间共同遵守的就是DOM规范。

因此,DOM规范同时约束它的实现者和使用者。DOM实现者必须实现规范中定义的所有接口,DOM使用者应该调用规范中相应的接口实现相应的功能。

如果你是实现者,需要关注如何实现DOM API;如果你是使用者,则只需关注如何使用DOM API。

它定义文档的逻辑结构,以及访问和操作文档的方式

上面这句话对 DOM API 作了更具体的解释,包括三层意思:

  • 定义文档的结构
  • 访问文档的方式
  • 操作文档的方式

HTML DOM 是对 DOM Core 的扩展,添加了专门针对 HTML 文档的特定对象和方法,它与现有的文档对象模型一致。下面我们就来讨论如何使用 HTML DOM API 的问题。

一、如何定义文档的逻辑结构?——节点对象树

DOM规范,将网页中的HTML文档抽象为内存中的节点对象树(DOM Tree)。树中的每一个节点对象对应HTML文档中的一个元素。

节点对象树

 

二、如何访问文档?——访问节点对象

(0) Document 接口作为文档入口

Document 接口代表整个文档。JavaScript 中的全局对象 document 是对 Document 接口的实现。

(1) 直接访问文档中的节点对象。

方法 描述
document.getElementsById("id"); 通过 id 属性获取节点对象
document.getElementsByName("name"); 通过 name 属性获取节点对象
document/element.getElementsByTagName("tag"); 通过 tag 属性获取节点对象
document/element.getElementsByClassName("class1[ class2]"); 通过 class 属性获取节点对象
document/element.querySelector("selector"); 通过 css 选择器 获取首个节点对象
document/element.querySelectorAll("selector"); 通过 css 选择器 获取所有节点对象

(2) 通过节点关系访问一个节点周围的节点对象。

关系 属性 描述
父节点(parent node) parentNode/parentElement 获取所属父节点对象
  ownerDocument 获取节点所属文档节点(根节点)对象
兄弟节点(sibling nodes) nextSibling
nextElementSibling
获取前一个兄弟节点对象
获取前一个兄弟元素节点对象
  previousSibling
previousElementSibling
获取后一个兄弟节点对象
获取后一个兄弟元素节点对象
子节点(child nodes) childNodes
children
获取所有子节点对象
获取所有子元素节点对象
  hasChildNodes(); 判断是否包含子节点对象
  childElementCount 获取子元素节点对象数量
  firstChild
firstElementChild
获取第一个子节点对象
获取第一个子元素节点对象
  lastChild
lastElementChild
获取最后一个子节点对象
获取最后一个子元素节点对象

 

三、如何操作文档?——操作节点对象

思路一:【节点对象】首先是一个【对象】,只要是对象就具有【属性】和【行为】。

元素节点p作为对象,id,class,style(该属性是一个对象)等作为对象的属性,onclick,onfocus,oninput 等作为对象的行为,具体的动作由 JavaScript 代码控制。

思路二:节点对象只包含属性 —— 特性属性样式属性行为(事件)属性

2018-01-03_101557

将【行为】看作对象的一种属性,以下实例印证了这一观点:

捕获1

我们获取节点对象的目的,就是为了操作节点对象本身以及节点对象的属性

(0) 操作节点对象本身

操作 方法 描述
创建节点 document.createElement("TAG");
document.createTextNode("#文本");
document.createComment("#注释");
document.createDocumentFragment();
document.createAttribute("myAttrName");
创建一个元素节点
创建一个文本节点
创建一个注释节点
创建一个空白的文档片段节点
创建一个属性节点
插入节点 parentNode.appendChild(newChild);
parentNode.insertBefore(newChild,refChild);
插入子节点(作为最后子节点)
插入子节点(在指定子节点之前)
删除节点 parentNode.removeChild(oldChild); 删除指定的子节点
替换节点 parentNode.replaceChild(newChild,oldChild); 替换一个子节点
克隆节点 node.cloneNode(deep); 克隆一个节点

(1) 操作节点对象的特性属性

方法 描述
e.特性名称[="value"]; 获取/设置特性值
e.getAttributeNames(); 获取已设置的全部属性名称(非IE内核)
e.getAttribute("特性名称"); 获取特性值
e.getAttributeNode("特性名称"); 获取特性节点[特性名称=特性值]
e.setAttribute("特性名称","特性值"); 设置特性值(不存在时新建该属性)
e.setAttributeNode(Attr); 设置特性节点

(2) 操作节点对象的样式属性

方法 描述
e.style.color[ ="颜色值"] 获取/设置标签内样式(内嵌样式)
window.getComputedStyle(e).color;
document.defaultView.getComputedStyle(e).color;
获取包括内嵌样式、<style>、<link>在内的最终样式(非IE内核 或 IE>8)
e.currentStyle.color 获取包括内嵌样式、<style>、<link>在内的最终样式(IE内核)

(3) 操作节点对象的行为(事件)属性

方法 描述
e.onclick[ =fun()];
e.onclick();
获取/设置事件
触发事件
e.addEventListener("type",listener,[useCapture]); 注册事件(非IE内核 或 IE>8)
e.attachEvent("ontype",listener); 注册事件(IE内核<11)
e.removeEventListener("type",listener,[useCapture]); 移除事件(非IE内核 或 IE>8)
e.detachEvent("ontype",listener); 移除事件(IE内核<11)
e.dispatchEvent(event) 调度(触发)事件

(4) 操作节点对象的内容(属性)

节点对象的内容,实际上是节点对象的子节点。传统的方法是使用新创建的子节点替换需要修改的旧子节点。

<html>
    <body>
        <div>
            <p>第一个段落</p>
            <p>第二个段落</p>
        </div>
    </body>
</html>
<script>
    //获取父节点
    var d = document.querySelector("div");
    //获取需要替换的旧子节点
    var oldChild = d.firstChild;
    //创建新子节点
    var newChild = document.createTextNode("新的文本");
    //替换
    d.replaceChild(newChild ,oldChild );
</script>

如此常用的操作,却有如此繁琐的操作过程,况且一次只能替换一个子节点,这也太坑了吧!别急,DOM 规范为我们提供了更加简便的操作。

转换一下思路,我们将节点对象的内容看作是节点对象的一个属性。那么方法 e.innerHTML 属性将以字符串的形式返回所有节点对象的内容。 e.innerHTML = newStr 将替换该内容。newStr 可以包含tag,替换的内容会自动转换为节点对象(其实简单的文本字符串,也会转换成一个文本节点)。

<script>
    //获取节点
    var d = document.querySelector("div");
    //修改节点内容
    var str = "新的文本";
    d.innerHTML= str;
</script>

最终的节点对象应该是下面这张图:

无标题

【The End】

posted @ 2018-01-03 16:23  flyingweb  阅读(4237)  评论(0编辑  收藏  举报