前言
文档对象模型(DOM,Document Object Model),表示由多层节点构成的文档,通过它可以增删改查页面的各个部分,以及修改一些属性、事件操作等。
一、节点类型
DOM总共有12种节点类型,常用的有:
- 元素节点 nodeType为1
- 属性节点 nodeType为2
- 文件节点 nodeType为3
// 判断节点类型,节点至少有nodeType(节点类型)、nodeName(节点名称)、nodeValue(节点值)
if (someNode.nodeType == 1) {
alert('Node is an element') // 这是一个元素节点
}
二、节点关系
- childNodes 返回类数组对象
- parentNode 指向父元素
- previousSibling 得到node的上一个兄弟节点
- nextSibling 得到node下一个兄弟节点
- firstChild 第一个节点
- lastChild 最后一个节点
- children 获取所有的子元素节点
<body>
<ul id="ul">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<div>
<span id="child"></span>
</div>
<script>
//1.获取span节点的父节点div
var spa = document.getElementById("child");
console.log(spa.parentNode);
//2.获取ul里面的所有的子节点li
var ul = document.getElementById("ul");
console.log(ul.childNodes);
//输出得到:NodeList(9) [text, li, text, li, text, li, text, li, text],是伪数组的形式
// 就是第一个li前有一个换行,属于文本节点text,总共有5个换行,即5个text
// 但实际开发中只需元素节点:可以使用nodeType(节点类型) 来判断是否是所需要的节点类型
// 元素节点:nodeType为1 属性节点:nodeType为2 文本节点:nodeType为3
// for(var i=0;i<ul.childNodes.length;i++){
// if(ul.childNodes[i]==1){
// console.log(ul.childNodes[i]);
// }
// }
// 以上太麻烦,会用第二种方式 获取所有子元素节点 parentNode.children(使用较多)
console.log(ul.children);
//HTMLCollection(4) [li, li, li, li],
//3.获取第一个和最后一个li
console.log(ul.firstChild);//#text
//因为返回第一个子节点,第一个是换行,文本节点text
console.log(ul.lastChild);//#text
//因为返回最后一个子节点,是一个换行,文本节点text
//返回第一个子元素节点,
console.log(ul.children[0]);//<li>1</li>
//返回最后一个子元素节点,
console.log(ul.children[ul.children.length-1]);// <li>4</li>
//IE9以上才支持
console.log(ul.firstElementChild);//<li>1</li>
console.log(ul.lastElementChild);// <li>4</li>
</script>
</body>
三、操作节点
因为所有关系指针都是只读的,所以DOM有提供了一些操纵节点的方法。
- appendChild(要增加的节点)
- insertBefore(newNode,指定元素)
- repalceChild(newNode,要替换的节点)
- removeChild(要删除的元素)
- cloneChild() // 克隆节点,传入true表示深克隆
// 添加新节点会更新相关的关系指针,包括父节点好之前的最后一个节点
let returnedNode = someNode.appendChild(someNode.firstChild)
alert(returedNode == someNode.firstChild) // true
alert(returedNode == someNode.lastChild) // true
// 如果添加已经存在的节点,那这个节点会从之前的位置移动到新位置。
let returnedNode = someNode.appendChild(someNode.firstChild)
alert(returedNode == someNode.firstChild) // false
alert(returedNode == someNode.lastChild) // true
// 作为最后一个节点插入
returnedNode = someNode.insertBefore(newNode,null)
alert(newNode == someNode.lastChild) // true
// 作为新的第一个子节点插入
returnedNode = someNode.insertBefore(newNode, someNode.firstChild)
alert(newNode == someNode.firstChild) // true
alert(returnedNode == newNode ) // true
// 替换第一个子节点
returnedNode = someNode.repalceChild(newNode, someNode.firstChild)
// 删除第一个子节点
returnedNode = someNode.repalceChild(someNode.firstChild)
简单版发布留言案例:
<body>
<!-- 一.HTML布局:
文本域和普通按钮上的文字显示的实现 -->
<textarea name="" id="" cols="30" rows="10"></textarea>
<button>发布</button>
<ul></ul>
<script>
//1.获取元素 点击按钮,创建li,给li的内容赋予文本域的值,最后将li添加到ul中
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
//2.注册事件
btn.onclick = function() {
// (1)首先在用户点击发布按钮时,判断用户有没有输入文字呀?文本域的内容用到value属性
if (text.value == "") {
alert('你没有输入内容');
return false;
} else {
//(1)创建元素
var li = document.createElement('li');
//有了li后才可以给li赋值
li.innerHTML = text.value;
//(2) 添加元素
ul.insertBefore(li,ul.children[0]);
}
}
</script>
</body>
四、修改属性
主要是修改DOM的元素属性,DOM元素的内容,属性,表单的值等
- 修改元素属性:src , href , title等
- 修改普通元素内容:innerHTML , innerText
- 修改表单元素:value , type , disabled
- 修改元素的样式: style , className
属性操作:
主要是对于自定义属性
- setAttibute: 设置DOM的属性值
- getAttribute: 得到DOM的属性值
- removeAttribute: 移除属性
五、查找DOM
- DOM提供的API元素:getElementByld , getElementsByTagName等
- H5提供的方法:querySelector querySelectorAll 提倡
- 利用节点操作获取元素:父(parentNode),子(children),兄(previousElementSibling, nextElementSibling)提倡
总结
1、我们获取过来的DOM元素是一个对象,所以DOM又称作文档对象模型;
2、对于HTML,DOM使得HTML形成一棵dom树,包含文档,元素,节点
3、对于dom操作,主要是对于元素的操作,主要有创建,增,删,改,查,属性操作,事件操作
参考:《JavaScript高级程序设计》、操作DOM总结(博客园)