1. 从ECMA到W3C
我们知道,ECMA定义的是js的变量语法等基础的标准规范,而W3C是针对浏览器API提出的规范, 所以我们要工作不可能只了解语法,我们的代码要在浏览器上跑起来就需要我们去了解W3C的标准。
那么W3C规定了哪一系列的的API呢,DOM、BOM、AJAX、事件、存储等等。window.document,这个就是W3C提出的浏览器内置更多的对象之一。
1.1 API的概念
API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组程序的能力,而又无需访问源码,无需理解其内部工作机制细节,只需直接调用使用即可。
总之API就是为我们程序员提供了一个接口,帮助我们实现某种功能。
1.2 Web API的概念
Web API 是浏览器提供的一套操作浏览器功能和页面元素的 API ( BOM 和 DOM )。
现阶段我们主要针对于浏览器讲解常用的 API , 主要针对浏览器做交互效果。
MDN 详细 API : Web API 接口参考 | MDN
2. 什么是DOM?
HTML DOM 是W3C (万维网联盟)制订的一套标准,标准中定义了所有 HTML 元素的对象和属性,以及访问它们的方法。换言之,HTML DOM 是关于如何获取、修改、添加或删除 HTML 元素的标准。
注意:DOM 是 Document Object Model(文档对象模型)的缩写。
3. DOM 节点
根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:
-
整个文档是一个文档节点
-
每个 HTML 元素是元素节点
-
HTML 元素内的文本是文本节点
-
每个 HTML 属性是属性节点
-
注释是注释节点
4. DOM 节点树
我们在了解DOM的时候,首先需要了解到一个DOM树的结构,这是一种树形的数据结构。下图就是DOM文档渲染出来的DOM树。DOM 将 HTML 文档视为树形结构。这种结构被称为节点树:
DOM树 又称为文档树模型,把文档映射成树形结构,通过节点对象对其处理,处理的结果可以加入到当前的页面。
-
文档:一个页面就是一个文档,DOM中使用document表示
-
节点:网页中的所有内容,在文档树中都是节点(标签、属性、文本、注释等),使用node表示
-
标签节点:网页中的所有标签,通常称为元素节点,又简称为"元素",使用element表示
-
DOM把以上内容都看做对象。(对象可以有属性和方法)
-
通过 HTML DOM,树中的所有节点均可通过 JavaScript 进行访问。所有 HTML元素(节点)均可被修改,也可以创建或删除节点。
5. 节点之间的关系
节点树中的节点彼此拥有层级关系,我们可以使用父(parent)、子(child)和同胞(sibling)等术语来描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹)。
-
在节点树中,顶端节点被称为根(root)
-
每个节点都有父节点、除了根(它没有父节点)
-
一个节点可拥有任意数量的子节点
-
同胞是拥有相同父节点的节点
6. 获取元素节点
为什么要获取页面元素?
例如:我们想要操作页面上的某部分(显示/隐藏,动画),需要先获取到该部分对应的元素,再对其进行操作。
假设页面中包含如下代码,我们怎样使用 DOM 提供的方法获取这些节点呢?
<div id="main">
<div class="box"> <p>段落内容</p> </div>
<div class="box"> <p>段落内容</p> </div>
<div class="box"> <p>段落内容</p> </div>
</div>
6.1 根据 id 获取元素
document.getElementById('main'); // 获取 id 属性值为 main 的元素
6.2 根据标签名获取元素
document.getElementsByTagName('p'); // 获取标签名为 p 的元素
6.3 根据 class 获取元素
document.getElementsByClassName('box'); // 获取 class 属性值包含 box 类名的元素
6.4 获取特殊元素
//1、获取整个文档元素HTML
document.documentElement
//2、获取body
document.body
//3.获取title
document.title
7. 修改节点
<p class="box">段落内容</p>
<p class="box">段落内容</p>
<p class="box">段落内容</p>
7.1 改变 HTML 内容
-
改变元素内容的最简答的方法是使用 innerHTML和innerText 属性。
var boxes = document.getElementsByClassName('box')[0]; boxes.innerHTML = 'Hello DOM'; // 修改段落中文本 boxes.innerText = 'Hello DOMText' // 修改段落中文本
-
除了修改文本以外,还可以将文本变成 HTML 标签
boxes.innerHTML = '<a href="#">链接</a>'; // 将段落中的文本修改成<a>元素
innerText和innerHTML的区别
-
获取内容时的区别:
innerText会去除空格和换行,而innerHTML会保留空格和换行
-
设置内容时的区别:
innerText不会识别html,而innerHTML会识别。
7.2 改变 CSS 样式
-
通过 HTML DOM,我们能够访问 HTML 元素的样式对象。
boxes.style.color = '#f00'; // 字体颜色修改成红色 boxes.style.fontSize = '12px'; // 字体大小修改成 12px
7.3 改变 HTML 属性
方法一:
获取属性的值
元素对象.属性名
设置属性的值
元素对象.属性名 = 值
表单元素中有一些属性如:disabled、checked、selected,元素对象的这些属性的值是布尔型。
方法二:
-
获取元素的属性值
boxes.getAttribute('class'); // 获取 class 属性的值
-
给元素添加/修改/删除属性
boxes.setAttribute('title', '段落的title属性内容'); // 设置 title 属性 // 移除属性 removeAttribute(属性) div.removeAttribute('class');
8. 操作HTML元素
<div id="main">
<p id="box1">段落内容</p>
<p id="box2">段落内容</p>
<p id="box3">段落内容</p>
</div>
8.1 输出到文档
方法:document.write(exp1,exp2,exp3,....)
作用:可以将任意字符串插入在文档中。
document.write("Hello World!");
document.write("<h1>Main title</h1>");
8.2 新建节点
方法:document.createElement(tagName);
作用:根据标签名(tagName)创建新的 DOM 对象。
这个方法只接受一个参数,要创建元素的标签名。例如,下面的代码创建了一个<p>元素:
var newElement = document.createElement('p'); // 创建新元素 p
8.3 新建文本节点
方法:document.createTextNode("文本");
作用:创建一个文本节点。
var newElement=document.createElement("p");
var textCon=document.createTextNode("Hello World");
newElement.appendChild(textCon);
document.body.appendChild(newElement);
8.4 追加节点
方法:parentElement.appendChild(newElement);
作用:追加到父元素内容的后面。
var parentElement = document.getElementById('main'); // 获取父元素
parentElement.appendChild(newElement); // 将新元素追加到父元素内容之后
8.5 插入节点
方法:parentElement.insertBefore(newElement, targetElement)
作用:将新创建的元素(newElement)添加到目标元素(targetElement)前面
var parentElement = document.getElementById('main'); // 获取父元素
var targetElement = document.getElementById('box2'); // 获取目标元素
var newElement = document.createElement('p'); // 创建新元素
//将新元素插入到目标元素之前
parentElement.insertBefore(newElement, targetElement);
注意:没有inertAfter这个方法。
8.6 替换节点
方法:parentElement.replaceChild(newElement, targetElement)
作用:使用新元素替换目标元素
被替换的节点将从文档树种移除,同时要插入的节点占据其位置。
var parentElement = document.getElementById('main'); // 获取父元素
var targetElement = document.getElementById('box2'); // 获取目标元素
var newElement = document.createElement('p'); // 创建新元素
parentElement.replaceChild(newElement, targetElement); // 使用新元素替换目标元素
8.7 删除节点
方法:parentElement.removeChild(childElement);
作用:从父元素(parentElement)中删除一个子元素(childElement)
var parentElement = document.getElementById('main'); // 获取父元素
var childElement = document.getElementById('box2'); // 获取子元素
parentElement.removeChild(childElement); // 将子元素从父元素中删除
注意:以上4个方法操作的都是某个节点的子节点,也就是说,要使用这几个方法必须先取得父节点。另外,并不是所有节点都有子节点,如果在没有子节点的节点上调用这些方法,将会出错。
8.8 删除本身节点remove()
var targetElement = document.getElementById('box');
//删除节点
targetElement.remove()
8.9 克隆节点
方法:currentElement.cloneNode(true/false);
作用:复制 DOM 元素。
该方法只接受一个布尔值的参数,true代表深度拷贝,false代表浅拷贝,不传参的话,默认为false。
var currentElement = document.getElementById('main'); // 获取需要复制的元素
currentElement.cloneNode(); // 只复制元素本身,忽略其子元素-false默认
currentElement.cloneNode(true); // 复制元素本身,及其子元素
注意:这个方法是所有节点都有的。如果不传递任何参数,默认只拷贝当前元素节点,如果传递的参数为true,就会进行深度拷贝,也就是被拷贝元素内的所有后代元素都会被复制。
9. 根据DOM节点层次关系获取元素
// 访问父节点(亲爸爸)
console.log(div.parentNode);
// 访问下一个兄弟节点
//包括空白节点(幽灵节点)
console.log(div.nextSibling);
//IE9以上才支持
console.log(div.nextElementSibling);
// 访问上一个兄弟节点
//包括空白节点(幽灵节点)
console.log(div.previousSibling);
//IE9以上才支持
console.log(div.previousElementSibling);
// 访问第一个孩子节点
//包括空白节点(幽灵节点)
console.log(div.firstChild);
//IE9以上才支持
console.log(div.firstElementChild);
// 访问最后一个孩子节点
//包括空白节点(幽灵节点)
console.log(div.lastChild);
//IE9以上才支持
console.log(div.lastElementChild);
// 访问孩子节点
//包括空白节点(幽灵节点)
console.log(div.childNodes);
console.log(div.children[1]);
9.1节点的类型名称及值
- nodeType 属性返回节点类型。
如果节点是一个元素节点,nodeType 属性返回 1。
如果节点是属性节点, nodeType 属性返回 2。
如果节点是一个文本节点,nodeType 属性返回 3。
如果节点是一个注释节点,nodeType 属性返回 8。
- nodeName 属性指定节点的节点名称。
如果节点是元素节点,则 nodeName 属性返回标签名。
如果节点是属性节点,则 nodeName 属性返回属性的名称。
对于其他节点类型,nodeName 属性返回不同节点类型的不同名称。
- nodeValue 属性设置或返回指定节点的节点值。
9.2 获取属性节点方法
总结
每天一总结,今天又有什么新的收获呢?你做好为明天奋战的准备了吗?