DOM
document object model文档对象模型
W3C就是在逐渐的规范化DOM但是IE显示会有问题
html中整个其实是一个树
DOM中的节点查找
节点分类
1、元素标签 div a
2、文本节点 标签内的纯文本
3、属性节点 标签的属性
查找元素
getelementById 传递一个ID值,找到对应的元素的文档对象,没有找到的话就返回null
getElementsByTagName返回的是一个数组集合,类数组
getElementsByName获取相同的name属性的元素返回的一个集合(有兼容),但是用于在表单上的时候没有兼容性(因为input有合法的name属性)
注意:getElementsByTagName(“*”)在火狐中会多匹配一个,是把文档声明也算进去了
注意
DOM操作必须在HTML文档加载完才可以执行
对属性进行操作
文档对象的自定义属性不能够通过 对象.属性 来获得,
但是可以通过 对象. getAttribute来获得
<div id="a1" title="a2" class="a3" style="font-size: 30px;color: red" bb="aa"><h1>
sasa
</h1></div>
var a=document.getElementById("a1");
console.log(a.bb); //undefined
console.log(a.getAttribute("bb")); //aa
setAttribute 接受两个参数值 属性和属性值 设置的是自定义的属性或者是系统的属性
removeAttribute 移除某一个属性
获取元素节点的属性
var a=document.getElementById("a");
console.log(a.tagName); //获取标签名字
console.log(a.innerHTML); //获取标签的文本内容(包含html的标签)而不是文本节点
innerHTML不仅可以获取标签中的文本内容也可以为其赋值改变标签中的文本内容。并且赋值的时候支持html代码
获取元素节点的html属性
var a=document.getElementById("a1");
console.log(a.id); //获取元素节点id属性的值
console.log(a.style); //获取元素节点style属性对象
console.log(a.style.color); //获取元素节点style对象的color值 red
console.log(a.title); //获取元素节点class属性的值
console.log(a.className); //获取元素节点class属性的值
上边的这些属性不仅可以获取,也可以为其赋值
可以为标签增加自定义属性,但是这个自定义属性的直接获取在各个浏览器中有兼容性(非IE都不支持)
查找、遍历DOM节点
元素节点 属性节点 文本节点
node节点的属性
nodeName
获取元素节点的标签名 和tagName等价值
nodeType
获取元素节点的类型值 1元素节点 2属性节点 3文本节点
nodeValue
元素节点本身没有内容会输出null
层次节点的属性
注意的是 在元素节点的空白也是文本节点 内容为空白 文本节点没有标签名
获取到文本节点的时候,是无法使用 innerHTML这个属性输出文本内容的。这个非标准的属性必须在获取元素节点的时候,才能输出里面包含的文本
PS: innerHTML和 nodeValue第一个区别, 就是取值的。 那么第二个区别就是赋值的时
候,nodeValue会把包含在文本里的 HTML转义成特殊字符,从而达到形成单纯文本的效果
而且nodeValue必须是节点本身
box.childNodes[0].nodeValue= '<strong>abc</strong>';//结果为: <strong>abc</strong>
box.innerHTML= '<strong>abc</strong>'; //结果为: abc
获取层次节点的方法
获取第一个节点 ,获取最后一个节点
html代码
<div id="a1" title="a2" class="a3" style="font-size: 30px;color: red" bb="aa">
<h1>
sasa
</h1>
</div>
js代码
var a=document.getElementById("a1");
console.log(a.childNodes.length); //3
console.log(a.firstChild.nodeValue); // 文本节点的值 空格
console.log(a.lastChild.nodeValue); // 文本节点的值 空格
console.log(a.ownerDocument); //返回文档的根节点 document 返回的nodeType类型为9
获取父节点、同级的上一个下一个节点
var a=document.getElementById("a1");
console.log(a.parentNode); //body
console.log(a.firstChild.nextSibling); //a第一个子节点的下一个同级节点 h1
console.log(a.lastChild.previousSibling); //a最后一个子节点的上一个同级节点 h1
获取节点的所有属性
节点的.attributes得到节点的所有的属性
html代码
<div id="a1" title="a2" class="a3" style="font-size: 30px;color: red">
<h1>
sasa
</h1>
</div>
js代码
var a=document.getElementById("a1");
console.log(a.attributes); //获取节点的所有属性
console.log(a.attributes[0].nodeType); //属性节点的类型值为2
console.log(a.attributes[0].nodeValue); //a1
console.log(a.attributes[1].nodeValue); //a2
console.log(a.attributes[1].nodeName); //title
console.log(a.attributes["style"].nodeValue); //font-size: 30px;color: red
解决将空白字符计入总的节点数的问题
html代码
<div id="a1" title="a2" class="a3" style="font-size: 30px;color: red">
<p>测试1</p>
<p>测试1</p>
<p>测试1</p>
</div>
js代码
var a=document.getElementById("a1");
console.log(a.childNodes.length) //应该输出3但是输出7
解决办法:
1、忽略空白字符
var a=document.getElementById("a1");
console.log(filterWhite(a.childNodes).length) //3
function filterWhite(node){
var ret=[];
for(var i=0;i<node.length;i++){
if(node[i].nodeType==3&&/^\s+/.test(node[i].nodeValue)){
continue;
}
else{
ret.push(node[i]);
}
}
return ret;
}
2、移除空白字符
var a=document.getElementById("a1");
console.log(RemoveWhite(a.childNodes).length) //3
function RemoveWhite(node){
for(var i=0;i<node.length;i++){
if(node[i].nodeType==3&&/^\s+/.test(node[i].nodeValue)){
node[i].parentNode.removeChild(node[i]); //注意的是:必须为removeChild传递要删除的节点
}
}
return node;
}
document.write的一个注意的现象
当document.write(“sasa”);这句话写在标签中不会重写html中的代码
但是如果写咋另外一个js文件的window.onload的function中,就会重写html中的低吗
节点操作
创建节点
创建标签节点 createElement
window.onload=function(){
var a=document.getElementById("a1");
var p=document.createElement("p");
a.appendChild(p); //添加到了末尾
}
创建文本节点 createTextNode
window.onload=function(){
var a=document.getElementById("a1");
var p=document.createElement("p");
var text=document.createTextNode("sasa");
p.appendChild(text);
a.appendChild(p);
}
在指定节点的前边创建insertBefore
先把指针跳到指定节点的父节点上才能使用
window.onload=function(){
var a=document.getElementById("a1");
var p=document.createElement("p");
var text=document.createTextNode("sasa");
p.appendChild(text);
a.parentNode.insertBefore(p,a); //父节点才可以调用insertBefore方法 注意的是有两个参数
}
实现了在a前面插入了一个节点p
但是ECMA没有提供insertAfter(新生成的节点,目标节点),自己编写一个函数实现insertAfter
window.onload=function(){
var a=document.getElementById("a1");
var p1=document.createElement("p");
var text1=document.createTextNode("sasa");
p1.appendChild(text1);
insertAfter(p1,a);
}
function insertAfter(newElement,targetElement){
var parent=targetElement.parentNode;
parent.insertBefore(newElement,targetElement.nextSibling);
}
添加节点
append insertBefor
替换节点
也是先要将指针指向父节点
window.onload=function(){
var a=document.getElementById("a1");
var p1=document.createElement("p");
var text1=document.createTextNode("sasa");
p1.appendChild(text1);
a.parentNode.replaceChild(p1,a); //注意有两个节点
}
节点的克隆
cloneChilld(true或者false) 指的是是否克隆节点的内容
var a=document.getElementById("a1");
a.appendChild(RemoveWhite(a.childNodes)[0].cloneNode(true));
移除节点
removeChild() 父节点来调用