1.DOM介绍
1.1 DOM介绍
HTML DOM 是W3C标准(是HTML文档对象模型的英文缩写,Document Object Model for HTML)。HTML DOM 定义了用于HTML的一系列标准的对象,以及访问和处理 HTML 文档的标准方法。
通过DOM,可以访问所有的 HTML 元素,连同它们所包含的文本和属性。可以对其中的内容进行修改和删除,同时也可以创建新的元素。HTML DOM 独立于平台和编程语言。它可被任何编程语言诸如Java、JavaScript 和 VBScript 使用。
1.2 DOM树
HTML DOM 定义了访问和操作HTML文档的标准方法。DOM 将 HTML 文档表达为树结构。
1.3 DOM节点
DOM是文档对象化模型(Document Object Model)的简称。使用过DHTML对象模型的开发者一定能非常熟练地操作HTML页面上的每个标记内容,但如果借助DOM技术, 我们就可以通过更加直接而且简易的方式达到同样的目的。
DOM技术被Internet Explorer5.0及以上版本的浏览器所支持,它采取一种非常直观且一致的方式将HTML文档进行模型化处理,并借此提供访问、导航和操作页面的简易编程接口。通过DOM技术,我们不仅能够访问和更新页面的内容及结构,而且还能操纵文档的风格样式。DOM由W3C 组织所倡导,这样,大多数浏览器都将最终支持这项技术。
DOM-Document Object Model ,它是W3C国际组织的一套Web标准,它定义了访问HTML文档对象的一套属性、方法和事件 。
1.3.1 节点层次
父子节点,同胞节点。
节点树中的节点彼此拥有层级关系。父(parent)、子(child)和同胞(sibling)等术语用于描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹)。
在节点树中,顶端节点被称为根(root) 每个节点都有父节点、除了根(它没有父节点) 一个节点可拥有任意数量的子节点 同胞是拥有相同父节点的节点
1.3.2 节点分类
常见的节点类型有:
元素节点 属性节点 文本节点 文档节点
这些节点他们都有自己的特点,每个节点的名称,节点的属性,节点对应的值都不相同。在我们平时的工作中,我们可以通过节点的值或名称来判断是什么节点。
1.3.3 节点的名称
nodeName 是只读的也就是不能被重新赋值修改
节点名称表
节点类型 | nodeName |
---|---|
元素节点的 | 标签名相同 |
属性节点的 | 属性名相同 |
文本节点的 | #text |
文档节点的 | #document |
注意:nodeName 始终包含 HTML 元素的大写字母标签名。
1.3.4 节点的值
nodeValue 属性规定节点的值。
节点值表
节点类型 | nodeValue |
---|---|
元素节点的 | 是 undefined 或 null |
文本节点的 | 文本本身 |
属性节点的 | 属性值 |
1.3.5 节点的类型
nodeType 属性返回节点的类型。nodeType 是只读的,同样是不可以被修改,只可以访问。
节点类型称表
元素类型 | nodeType |
---|---|
元素 | 1 |
属性 | 2 |
文本 | 3 |
注释 | 8 |
文档 | 9 |
元素节点其实就是我们的标签。
1.4 DOM和DHTML对象模型的比较
可以这么说,DOM是从DHTML对象模型发展而来的。但更准确而言,DOM更象是对DHTML对象模型进行了根本变革的产物。
借助DHTML对象模型技术,我们能够单独地访问并更新HTML 页面上的对象,每个HTML标记通过它的ID和NAME属性被操纵,每个对象都具有自己的属性、函数和事件,通过函数操纵对象,通过事件触发因果过程。
DOM则要比DTHML对象模型功能更全面,它提供了一个对整个文档的访问模型,而不仅仅再局限于单一的HTML标记(Tag) 范围内。DOM将文档描绘为一个树形(Tree)结构,Tree的每个节点表现为一个HTML标记或者HTML标记内的文本项。树形结构精确地描述了HTML文档中标记间以及文本项间的相互关联性,这种关联性包括child(孩子)类型、parent(双亲)类型和兄弟(sibling)类型。
使用DHTML对象模型访问和更新HTML页面内容时,不可避免地需要查询相关技术手册。因为HTML对象很多,每个HTML对象又有很多的属性、函数和事件。但是采用DOM技术访问和更新HTML页面内容时,任何手册都可以放在一边了。首先查看一下HTML源代码,推算出页面的Tree结构模型;然后,按照层次结构关系操纵需要的属性。比如要更新页面上的文本项内容, 如果采用DTHML对象模型,需要使用到innerHTML属性,但必须要注意并不是所有的HTML对象都支持innerHTML属性;如果采用DOM技术,只要修改相关Tree节点都具有的nodeValue属性值即可。
DOM技术使我们可以方便地沿着文档的树型结构在上、下以及一侧方向做节点导航,从页面的任何地方开始,使用child、parent或者sibling三种关联性组成的表达式代表页面的另外地方。而DTHML对象模型不包含Tree结构,所以也就不具备页面对象的相互导航功能。当我们从一个标记对象开始时,不可能用关联表达式来表达相近的标记。虽然对于某些标记,比如TABLE,DHTML对象模型可以提供特殊的属性和函数存取相关内容, 但实现方式和效果远不如DOM技术显得一致化和直观化。采用DTHML对象模型访问TABLE中的单元(cell)内容时,首先要查询手册确定单元的坐标值i、j, 然后再通过表达式tableObj.rows[i].cells[j].innerHTML实现访问。但对于DOM来说,访问TABLE每个单元的内容将变得非常简单,只需要建立一个节点导航表达式就可以。
另外,DOM技术允许我们操纵文档的Tree结构,这包括创建新节点(nodes)、删除存在的节点以及在Tree中移动节点。实际上, 这就是执行创建新标记(tags)、删除存在的标记以及在文档中移动标记的过程。DTHML对象模型则不允许更改文档结构,我们只能操纵现有的对象。
与DHTML对象模型相比较,DOM只有一个缺憾:DOM不能支持事件处理,而DTHML对象模型对于文档对象则拥有一个广泛的事件处理功能。
2.节点操作
2.1 获取节点
我们获取节点的方法有很多,最基础常用的有
通过使用 getElementById() 方法 通过使用 getElementsByTagName() 方法 通过使用 getElementsByClassName() 方法
注意: 我们获取节点最重要的返回的是一个节点还是一个节点数组。这个问题一定要搞清楚,不然会影响我们的思考。这也是初学者常犯的错误。
具体使用的方法是:
node.getElementById("id");
节点.getElementById("ID值")
getElementById
//通过ID获取节点 【返回具体某个节点】
getElementsByTagName
//通过标签名获取节点 【返回节点数组,即使只有一个】
getElementsByName
// 通过标签的name值获取节点 【返回节点数组】
getElementsByClassName
//通过class值来获取节点 【返回节点数组】
querySelect("选择器") 【根据选择器返回找到结果集中的第一个】
querySelectAll("选择器") 【根据选择器返回找到的结果集,是个节点数组】
注意:
1.我们的getElementsByClassName这个方法在Internet Explorer 5,6,7,8 中无效。
2.我们使用这些方法可以是某个具体的节点,如果是某个具体的节点那就是从这个节点往下寻找,如果不确定是从哪往下找,我们一般使用根节点,文档节点调用方法
我们使用这些方法可以是某个具体的节点,如果是某个具体的节点那就是从这个节点往下寻找,如果不确定是从哪往下找,我们一般使用根节点,文档节点调用方法**
如:
// 找到文档节点,然后在内部寻找id值为bb的节点
document.getElementById("bb");
3. 当然我们还可以使用节点关系来寻找到某些的节点
如:
// 通过id值aa获取到节点赋给变量aa
var aa = document.getElementById("aa");
// 获取aa的父节点
console.log(aa.parentNode)
4. 注意空白文本节点
HTML代码
<div>
<button>你好</button>
</div>
JS代码
// 因为ByTagName的方法获取到的是节点数组,我们如果页面里只有一个div,这个时候就是这个节点数组的第一个元素
var div = document.getElemetsByTagName("div")[0];
console.log(div.childNodes)
console.log(div.children)
大家会发现输出的是一个数组,数组的个数为3个,为什么是三个?明明只有一个button节点,其实错了。还包含了两个空白的文本节点。但是下面那个却只输出了一个节点。为什么呢?
childNodes返回的是节点的子节点集合,包括元素节点、文本节点还有属性节点。【小坑:在火狐浏览器里,childNodes相当于children,只获取元素节点】
children返回的只是节点的元素节点集合,所以返回的只有button元素。
2.2 创建和插入节点
如果想往DOM 添加新元素,我们必须首先创建该元素(元素节点),然后向一个已存在的元素追加该元素。
2.2.1 创建节点
语法:
//创建一个元素节点
document.createElement("标签名")
//创建一个文本节点
document.createTextNode("文本内容")
注意:如果我们使用for循环不断的创建,然后直接放入到页面里这是极高的损耗浏览器性能的,所以我们创建代码片段(为避免频繁刷新DOM,可以先创造代码片段,完成所有节点操作之后统一添加到DOM中)
createDocumentFragment()
2.2.2 插入节点
插入节点有两种办法,第一种思路是插入到某个节点的内部的尾部我们称为appendChild,这个时候我们只需要知道是哪个父节点需要放子节点就可以了;第二种思路是插入到某个节点的的内部的某个节点的前面,这个时候我们就需要知道父节点是什么,同时我们还需要知道子节点是哪个,才好放在谁前面。
插入内部的尾部
语法:
父节点.appendChild(创建的节点)
// 找到ID为box的节点
var box = document.getElementById("box");
// 创建一个div节点
var aaa = document.createElement("div");
// 将aaa节点放入到box节点内的尾部
box.appendChild(aaa);
插入内部的某个前面
语法:
父节点.insertBefore(创建的节点,已知的子节点)
// 找到ID为box的节点
var box = document.getElementById("box");
// 创建一个div节点
var aaa = document.createElement("div");
// 将aaa节点放入到box节点内的第一个子节点前面,
创建的这个节点就变成了第一个子节点
box.insertBefore(aaa,box.firstChild);
上面这个代码比较有意思,我们实现了将新创建的节点放到需要放的节点里面的第一个的位置。
2.3 替换节点
替换节点是我们将某个子节点替换成我们自己想要的节点
语法:
父节点.replaceChild(新节点,老节点)
// 找到ID为box的节点
var box = document.getElementById("box");
// 创建一个div节点
var aaa = document.createElement("div");
// 将box里面的最后一个子节点替换成我们自己创建的节点
box.replaceChild(aaa,box.lastChild);
2.4 克隆节点
克隆节点就是将我们需要的节点复制一份,我们的克隆节点有深度克隆和浅克隆。
深度克隆: 包含子节点一起克隆。 浅克隆: 只会将找到的这个节点克隆,子节点不会克隆
语法:
需要被复制的节点.clone(true/false);
true: 复制当前节点以及所有子节点
false: 仅复制当前节点
// 找到class的值为box的第一个
var box = document.getElementsByClassName("box")[0];
// 克隆节点赋给变量
var curbox = box.clone(true);
// 放入到body里面去
var body = document.getElementsByTagName("body")[0];
body.appendChild(curbox);
2.5 删除节点
删除节点就是从我们的页面中删除这个节点。我们需要去找到需要删除的节点的父节点,然后在去使用removeChild方法删除对应的节点。
语法:
父节点.removeChild(子节点)
var box = document.getElementsByClassName("box")[0];
var body = document.getElementsByTagName("body")[0];
body.removeChild(box);
切记:调用删除方法的节点必须是要被删除节点的父节点。
3. 节点属性操作
我们每个节点都是有很多属性的,有一些属性是某些节点所特有的,有些时所有节点都有的属性。如id,class,title等等。还有一些我们称之为自定义属性 是以data-开头的属性。
HTML代码:
<div id="box" data-str="javascript">
教程
</div>
这个data-str就是我们的自定义属性,切记我们的自定义属性必须要以data-开头!
3.1 获取属性
由于我们的节点也是对象,所以我们的节点的属性我们可以通过前面我们对象的访问属性的方法用点去访问,同时我们DOM节点对象还单独提供了getAttribute()方法获取属性。
语法:
节点.属性名
// 用点号获取 【方法一】
节点.getAttribute("属性名")
// 用getAttribute获取 【方法二】
但是这二者有什么区别呢?
方法一只能获取已经包含的属性,不能获取自定义属性 方法二是所有的属性都可以获取
如我们要获取上面的HTML中DIV节点的属性
var box = document.getElementById("box");
console.log(box.id); // 输出 "box"
console.log(box.getAttribute("data-str")); //输出javascript
3.2 设置属性
设置属性的方法很简单,也有两种方法和上面基本对应
语法:
节点.属性名 = 属性值;
【方法一】
节点.setAttribute("属性名",属性值);
【方法二】
var img = document.getElementsByTagName("img")[0];
img.src = "img/aaa.png"; // 设置图片路径
img.setAttribute("alt","很帅!")
img.setAttribute("data-aaa","非常帅")
3.3 删除属性
删除属性有两种方法,第一种是将这个属性名对应的属性值置位空;第二种是将节点上对应的这个属性给删除了。 第一种方法并不是真正的删除。
语法:
节点.属性名 = "";
节点.removeAttribute("属性名");
// 将节点上这个属性删除
4. 节点文本操作
4.1 获取文本
获取文本的方法我们主要是通过访问节点的属性去获得,但是有几个不同的属性
语法:
节点.innerHTML
//获取节点下的所有内容包含了标签
节点.innerText
// 获取节点下的文本内容,会过滤掉标签
节点.value
// 获取input输入框等控件的内容
HTML代码
<div>
<button>你好</button>
</div>
<input value="20" />
JS代码
var div = document.getElementsByTagName("div")[0];
console.log(div.innerHTML);
// 输出 "<button>你好</button>"
console.log(div.innerText);
// 输出 "你好"
var input = document.getElementsByTagName("input")[0];
console.log(input.value); // 输出 20
4.2 设置文本
设置文本的方法基本使用的方法和上面获取差不多,都可以直接进行赋值。
语法:
节点.innerHTML = "文本内容"
// 会翻译html标签
节点.innerText = "文本内容"
// 不会翻译html标签
节点.value = 值
节点.setAttribute("value",值)
// 因为value是属性,所以也可以中这个方法设置内容
HTML代码
<div>
<button>你好</button>
</div>
<div>
<button>你好</button>
</div>
<input value="20" />
JS代码
var div1 = document.getElementsByTagName("div")[0];
var div2 = document.getElementsByTagName("div")[1];
div1.innerHTML = "<b>123</b>";
div2.innerText = "<b>123</b>";
var input = document.getElementsByTagName("input")[0];
input.value = 100;
input.setAttribute("value",200)
注意:如果我们的节点原本有内容,我们有赋入他内容,那么就会把原来的覆盖了。
4.3 删除文本
删除文本内容没有什么好的办法就是将我们的文本内容置为空。
语法:
节点.innerHTML = ""
// 内部什么都没了
节点.innerText = ""
// 内部什么都没了
节点.value = ""
节点.removeAttribute("value")
PS:纯属本人原创,如有错误 欢迎指点 不才会及时更正 互相学习