一、DOM接口
dom结构树代表的是一系列继承关系
例:Document和document的关系
document 继承自 HTMLDocument.prototype。
HTMLDocument.prototype 继承自 Document.prototype
原型是不是一个对象?
<script>
HTMLDocument.prototype = {
__proto__: Document.prototype.abc = "abc"
}
</script>
DOM结构树中,Node也是构造函数,comment是注释
HTMLDocument和HTMLElement实际上并列了对应的XML,但是因为不用了,XML就省略了。
HTMLHeadElement就是head标签,其余类推
<script>
// document--->HTMLDocument.prototype-->Document.prototype
HTMLBodyElement.prototype.abc = "demo";
var body = document.getElementsByTagName('body')[0];
var head = document.getElementsByTagName('head')[0];
</script>
上面如果HTMLElement.prototype.abc=“demo”;定义,则上面两个都能用
看看一层返回的是什么东西
二、DOM基本操作
1、getELementById方法定义在Document.prototype上,即ELement节点上不能使用
2、getElementsByName方法定义在HTMLDocument.prototype上,即非html中的document以外不能使用(xml document,Element)
3、getElementsByTagName方法定义在Document.prototype和ELement.prototype上
例:选div里面的span
<div>
<span>1</span>
</div>
<span></span>
<script>
// document--->HTMLDocument.prototype-->Document.prototype
var div = document.getElementsByTagName('div')[0];
var span = div.getElementsByTagName('span')[0];
</script>
开发中,经常利用先选择的父级,在他父级里面再次选什么元素来定位一个元素
4、HTMLDocument.prototype定义了一些常用的属性,body、head分别指代HTML文档中的 <body><head>
标签
5、Document.prototype上定义了documentELement属性,指代文档的根元素,在HTML文档中,他总是指代<html>
元素
6、getElementsByClassName、querySelectorAll、querySelector 在 Document,Element 类中均有定义
三、习题
1、遍历元素节点树
要求不能用 children 属性(在原型链上编程)
<div>
<p></p>
<span>
<strong></strong>
<b></b>
</span>
</div>
低级方法,给一个父节点,把子节点全部遍历出来,并打印
高级方法:打印树形结构
分层打印出来
先看div再看子元素节点,再挨个判断
2、封装函数,返回元素e的第n层祖先元素
<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>
3、封装函数,返回元素 e 的第 n 个兄弟节点,
(n 为正,返回后面的兄弟节点,n 为负,返回前面的,n 为 0,返回自己。)
<div>
<span></span>
<p></p>
<strong></strong>
<!-- this is comment -->
<i></i>
<address></address>
</div>
<script>
function retSibling(e, n) {
while (e && n) {
if (n > 0) {
e = e.nextElementSibling;
n--;
} else {
e = e.previousElementSibling;
n++;
}
}
return e;
}
var strong = document.getElementsByTagName('strong')[0];
</script>
上面在 ie9 以下不能用。考虑到兼容性,可以按照下面思路写
<div>
<span></span>
<p></p>
<strong></strong>
<!-- this is comment -->
<i></i>
<address></address>
</div>
<script>
function retSibling(e, n) {
while (e && n) {
if (n > 0) {
if (e.nextElementSibling) {
e = e.nextElementSibling;
} else {
e = e.nextSibling;
if (e.nodeType != 1) {
e = e.nextSibling;
if (e.nodeType != 1) {
e = e.nextSibling;
}
}
}
n--;
} else {
e = e.previousElementSibling;
n++;
}
}
return e;
}
var strong = document.getElementsByTagName('strong')[0];
</script>
1是元素节点返回值,用for循环和三目运算符
<script>
function retSibling(e, n) {
while (e && n) {
if (n > 0) {
if (e.nextElementSibling) {
e = e.nextElementSibling;
} else {
for (e = e.nextSibling; e && e.nodeType != 1; e = e.e.nextSibling) {};
}
n--;
} else {
if (e.previousElementSibling) {
e = e.previousElementSibling;
} else {
for (e = e.previousSibling; e && e.nodeType != 1; e = e.e.previousSibling) {};
}
n++;
}
}
return e;
}
var strong = document.getElementsByTagName('strong')[0];
</script>
如果
for(){}
循环的执行体是空的,那么可以不写{}
4、编辑函数,封装 children 功能,解决以前部分浏览器的兼容性问题
<div>
<b></b> abc
<!-- this is comment -->
<strong>
<span>
<i></i>
</span>
</strong>
</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>
5、自己封装hasChildren()方法,不可用children属性
<div>
<b></b> abc
<!-- this is comment -->
<strong>
<span>
<i></i>
</span>
</strong>
</div>
<script>
var i = document.getElementsByTagName("i")[0];
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) {
return true;
}
}
return false;
}
var div = document.getElementsByTagName("div")[0];
var i = document.getElementsByTagName("i")[0];
</script>
四、DOM基本操作
1、增
document.createElement();
//增加或创建元素节点(标签)—常见
例:在括号里面写什么字符串,就创建什么标签
第一张加上了123
但是页面里面没有显示,用第二张的方法即可
document.body.appendChild(“div”)
document.createTextNode();//创建文本节点
document.createComment();//创建注释节点
document.createDocumentFragment();//创建文档碎片节点
2、插——剪切操作
parentNode.appendChild();可以理解成.push
<div>
</div>
<script>
var div = document.getElementsByTagName("div")[0];
var text = document.createTextNode("abc");
var span = document.createElement("span");
div.appendChild(text);
div.appendChild(span);
var text1 = document.createTextNode("demo");
span.appendChild(text1);
</script>
把abc插入到span里面去
<div>
</div>
<script>
var div = document.getElementsByTagName("div")[0];
var text = document.createTextNode("abc");
var span = document.createElement("span");
div.appendChild(text);
div.appendChild(span);
var text1 = document.createTextNode("demo");
span.appendChild(text1);
span.appendChild(text);
</script>
例:把span放div里面
<div></div>
<span></span>
<script>
var div = document.getElementsByTagName("div")[0];
var span = document.getElementsByTagName("span")[0];
div.appendChild(span);
</script>
parentNode.insertBefore(a,b);
一定是div先insert a,before b
<div>
<span></span>
</div>
<script>
var div = document.getElementsByTagName("div")[0];
var span = document.getElementsByTagName("span")[0];
var strong = document.createElement("strong");
div.insertBefore(strong, span);
</script>
在div后,span前插入strong
在 div 后,span 前插入 strong 的基础上,把 i 放 strong 前面
3、删
parent.removeChild();//就是被剪切出来了
<div>
<span></span>
</div>
<script>
var div = document.getElementsByTagName("div")[0];
var span = document.getElementsByTagName("span")[0];
var strong = document.createElement("strong");
var i = document.createElement("i");
div.insertBefore(strong, span);
div.insertBefore(i, strong);
</script>
child.remove();//自尽,完全删除
4、替换
parent.replaceChild(new,origin)
//用新的new去置换旧的origin