什么是DOM
- DOM --> Document Object Model
- DOM定义了表示和修改文档所需的方法。DOM对象即为宿主对象,由浏览器厂商定义,用来操作html和xml功能的一类对象的集合。也有人称DOM是对HTML以及XML的标准编程接口。
查看元素节点
- document代表整个文档
- document.getElementById()
- .getElementsByTagName()
- .getElementsByName() // 需注意,只有部分标签name可生效(表单,img, iframe)
- .getElementsByClassName() // 类名
- .querySelector() //css选择器 不是实时的,一般不用
- .querySelectorAll() // css选择器 不是实时的,一般不用
节点的类型
- 元素节点 —— 1
- 属性节点 —— 2
- 文本节点 —— 3
- 注释节点 —— 8
- document —— 9
- DocumentFragment —— 11
遍历节点树:
注意:是遍历节点
- parentNode -> 父节点 (最顶端的parentNode为#document)
- childNodes -> 子节点们
- firstChild -> 第一个子节点
- lastChild -> 最后一个子节点
- nextSibling -> 后一个兄弟节点
- previousSibling ->前一个兄弟节点
基于元素节点树的遍历
- parentElement ->返回当前元素的父元素节点(IE不兼容)
- children -> 只返回当前元素的元素子节点
- node.childElementCount === node.children.length 当前元素节点的第一级子元素的数量
- firstElementChild -> 返回的是第一个元素节点 (IE不兼容)
- lastElementChild -> 返回的是最后一个元素节点 (IE不兼容)
- nextElementSibling/previousElementSibling -> 返回后一个/前一个兄弟元素
节点的四个属性
- nodeName : 元素的标签名,以大写形式表示,只读
- nodeValue : Text节点或Comment节点的文本内容,可读写
- nodeType : 该节点的类型,只读
- attributes : Element节点的属性集合
节点的一个方法
Node.hasChildNodes(); // 是否有子节点
示例代码: 获取某个元素里的所有一级子元素节点、
<body>
<div>
123
<p>123</p>
<strong>
<span></span>
</strong>
<em></em>
<i></i>
</div>
<div></div>
<div></div>
<script>
// 不用children
var div = document.getElementsByTagName('div')[0];
function retElementChild(node) {
var temp = {
length : 0,
push : Array.prototype.push,
splice : Array.prototype.splice
},
child = node.childNodes,
len = child.length;
for(var i = 0; i < len; i++){
if(child[i].nodeType === 1) {
temp.push(child[i]);
}
}
return temp
}
console.log(retElementChild(div));
</script>
</body>
输出结果:
### 课堂练习
- 遍历元素节点树(在原型链上编程)
<body>
<div>
<div>
<span>
<a href="" title=""></a>
</span>
</div>
<span></span>
</div>
<div>
<div>
<div>
<span></span>
</div>
</div>
</div>
<script>
var div=document.getElementsByTagName("div")[0];
var a=[];
HTMLElement.prototype.allElements=function(){
var dom=this
for(var i=0;i<dom.children.length;i++){
a.push(dom.children[i])
if(dom.children[i].hasChildNodes()){
// console.log(this.children[i].children[i])
dom.children[i].allElements();
}
}
return a;
}
console.log(div.allElements());
</script>
</body>
输出结果:
2. 封装函数,返回元素e的第n层祖先元素节点
<body>
<div>
<strong>
<span>
<i></i>
</span>
</strong>
</div>
<script>
function retParent(elem, n) {
while(elem && n) {
elem = elem.parentElement;
n--;
}
return elem;
}
var i = document.getElementsByTagName('i')[0];
</script>
</body>
- 封装函数,返回元素e的第n个兄弟元素节点,n为正,返回后面的兄弟元素节点,n为负,返回前面的,n为0,返回自己
<body>
<div>
<em></em>
<span></span>
<p></p>
<strong></strong>
<em></em>
</div>
<script>
function retSibling(e,n) {
while(e && n){
if(n>0) {
if(e.nextElementSibling){ // 兼容IE9以下
e = e.nextElementSibling;
}else{
for(e = e.nextSibling; e && e.nodeType != 1; e = e.nextSibling);
}
n--;
}else{
if(e.previousElementSibling){
e = e.previousElementSibling;
}else{
for(e = e.previousSibling; e && e.nodeType != 1; e = e.previousSibling);
}
n++;
}
}
return e;
}
var strong = document.getElementsByTagName('strong')[0];
</script>
</body>
- 编辑函数,封装myChildren功能,解决以前部分浏览器的兼容性问题
<body>
<div>
<strong>
<span>
<i></i>
</span>
</strong>
<p></p>
</div>
<script>
Element.prototype.myChildren = function() {
var child = this.childNodes;
var len = child.length;
var arr = [];
for(var i = 0; i<len; i++) {
if(child[i].nodeType == 1) {
arr.push(child[i]);
}
}
return arr;
}
var div = document.getElementsByTagName('div')[0];
</script>
</body>
- 自己封装hasChildren()方法,不可用children属性
判断是否有子元素
<body>
<div>
<strong>
<span>
<i></i>
</span>
</strong>
<p></p>
</div>
<script>
Element.prototype.hasChildren = function() {
var child = this.childNodes;
var len = child.length;
for(var i = 0; i<len; i++) {
if(child[i].nodeType == 1) {
return true;
}
}
return false;
}
var div = document.getElementsByTagName('div')[0];
</script>
</body>