DOM操作
一、DOM的含义
* 文档对象模型
* DOM是关于创建,插入,修改,删除页面元素的标准
* DOM赋予我们操作页面的能力
*
* 页面的内容都是字符串,JS会把这些字符串转成DOM树,DOM树会把字符串转成节点,其实我们操作DOM的根本就是操作节点二、DMO节点
<script>
/*
* attributes
* 属性节点
* 返回元素身上的所有属性节点,每个属性都会有一个自己对应的下标
* 它有一个length属性,代表元素身上有多少个属性节点
*
* childNodes
* 元素身上的第一层子节点,返回元素身上的所有子节点的集合(第一层)
子节点包含 文本节点、元素节点、注释节点
*
* nodeName
* 节点的名称
*
* nodeType
* 节点的类型
* 返回的是一个数字
*
*/
window.onload=function(){
var box=document.getElementById("box");
var attr=box.attributes;//元素属性节点的集合
console.log(attr);
console.log(attr[0]);//id="box"
var child=box.childNodes;//元素子节点的集合
console.log(child);
//元素节点(标签)
console.log(box.nodeName);//DIV
console.log(box.nodeType);//1
//属性节点
console.log(attr[0].nodeName);//id
console.log(attr[0].nodeType);//2
//文本节点
console.log(child[0].nodeName);//#text
console.log(child[0].nodeType);//3
//注释节点
console.log(child[3].nodeName);//#comment
console.log(child[3].nodeType);//8
//文档节点
console.log(document.nodeName);//#document
console.log(document.nodeType);//9
}
</script>
<div id="box"class="color" style="width: 100px;">
<p><span></span></p>
kaivon
<!--这里是注释-->
</div>
三、tagName
* 节点名称,任何一个节点都有这个属性
*
* tagName
* 标签名称(全大写)
* 只有元素节点才有这个属性window.onload=function(){
var box=document.getElementById("box");//元素节点
var child=box.childNodes;
console.log(child[0].nodeName);//#text
console.log(child[1].tagName);//undefined
console.log(child[1].nodeName);//SPAN
console.log(child[1].tagName);//SPAN
console.log(box.nodeName);//DIV
console.log(box.tagName);//DIV
console.log(document.nodeName);//#document
console.log(document.tagName);//undefined
}
<div id="box">
<span>aaa</span>
</div>
四、parentNode
* 元素的父节点
*
* 属性节点是没有父节点window.onload=function(){
var box=document.getElementById("box");
var p=box.querySelector('p');//元素节点
console.log(p.parentNode);//div
var attr=p.attributes;//属性节点
console.log(attr[0].parentNode);//null
var child=box.childNodes;//box里的所有子节点
console.log(child[3].parentNode);//div#box
};
<div id="box">
<p style="width: 100px;"></p>
<!--这里是注释-->
</div>
五、children
* 获取到父级下的第一层子元素,它是一个集合,代表所有的子元素
* 每个子元素都有一个对应的下标
* 它还有一个length属性,代表子元素的个数
* 这个children只选择到标签 不包含文本和注释
* 非标准
*
* childNodes
* 获取元素的第一层的所有子节点,包含文本、注释 s
window.onload=function(){
var ul=document.querySelector("ul");
console.log(ul.childNodes);
//所以需要用调用函数
function getChild(parent){
var child=parent.childNodes;
var arr=[];
for(var i=0;i<child.length;i++){
if(child[i].nodeType==1){
//nodeTy==1是标签
arr.push(child[i]);
}
}
return arr;
}
var lis=getChild(ul);
console.log(lis);
}
</script>
<ul>
<li><span>隐藏1</span></li>
<li><span>隐藏2</span></li>
<li><span>隐藏3</span></li>
<li><span>隐藏4</span></li>
<li><span>隐藏5</span></li>
<!--这里是注释-->
</ul>
六、previousElementSibling
* 找到上一个兄弟节点
* 如果找不到的话就返回一个nullwindow.onload=function(){
var lis=document.querySelectorAll("li");
lis[1].previousElementSibling.style.background='red';//下标数为0的li背景变红
console.log(lis[0].previousElementSibling);//null
lis[0].previousElementSibling.style.background='red';//报错
}
</script>
<ul>
<li><span>隐藏1</span></li>
<li><span>隐藏2</span></li>
<li><span>隐藏3</span></li>
<li><span>隐藏4</span></li>
<li><span>隐藏5</span></li>
</ul>
7.nextElementSibling
* 找到下一个兄弟节点
* 如果找不到的话返回一个nullwindow.onload=function(){
var lis=document.querySelectorAll("li");
lis[0].nextElementSibling.style.background='red';//小标数为1的li背景变红
console.log(lis[4].nextElementSibling);//ull
lis[4].nextElementSibling.style.background='red';
}
</script>
<ul>
<li><span>隐藏1</span></li>
<li><span>隐藏2</span></li>
<li><span>隐藏3</span></li>
<li><span>隐藏4</span></li>
<li><span>隐藏5</span></li>
</ul>
8.firstElementChild
* 父级.firstElementChild
* 找到第一个子节点window.onload=function(){
var ul=document.querySelector("ul");
ul.firstElementChild.style.background='red';//获取第一个li
}
</script>
</head>
<body>
<ul>
<li><span>隐藏1</span></li>
<li><span>隐藏2</span></li>
<li><span>隐藏3</span></li>
<li><span>隐藏4</span></li>
<li><span>隐藏5</span></li>
</ul>
9、lastElementChild
* 父级.lastElementChild
* 找到最后一个子节点window.onload=function(){
var ul=document.querySelector("ul");
ul.lastElementChild.style.background='red';//获取到ul下的最后一个li
};
</script>
</head>
<body>
<ul>
<li><span>隐藏1</span></li>
<li><span>隐藏2</span></li>
<li><span>隐藏3</span></li>
<li><span>隐藏4</span></li>
<li><span>隐藏5</span></li>
</ul>
10、offsetParent
* 作用
* 获取离元素最近的有定位的父级
* 它会一层一层往上找,直到找到最近的有定位的父级后就把这个父级返回
* 如果父级都没有定位,那返回body(IE8以及IE8以上)
*
* 语法
* 元素.offsetParent
* 注意
* 遵循一个原则,父级一定要给一个定位
* body是没有offsetParent<style>
div{
width:100px;
height:100px;
border:1px solid #f00;
margin:70px0070px;
}
#box2{
position: absolute;
}
#box4{
position: relative;
}
</style>
<script>
window.onload=function(){
var box1=document.getElementById("box1");
var box3=document.getElementById("box3");
console.log(box1.offsetParent);//box2
box1.offsetParent.style.background='red';
console.log(box3.offsetParent);//box4
box3.offsetParent.style.background='blue';
console.log(document.body.offsetParent);//null
}
</script>
</head>
<body>
<div id="box4">box4
<div id="box3">box3
<div id="box2">box2
<div id="box1">box1</div>
</div>
</div>
</div>
</body>
11、offsetLeft &offsetTop
* 作用
* 找到元素最左边离最近的有定位的父级之间的距离,不带单位,并且不带边框
* 语法
* 元素.offsetLeft
*
* offsetTop
* 作用
* 找到元素最上边离最近的有定位父级之间的距离,不带单位,并且不带边框
*
* 注意
* 如果没有定位的父级,那默认是到html的距离
* 遵循一个原则:1、给父级定位;2、一上来把默认样清掉 作用:提示层例子
<style>
div{
width:100px;
height:100px;
border:50px solid #f00;
margin:70px0070px;
}
body{
border:1px solid #f00;
}
#box2{
position: absolute;
}
</style>
<script>
window.onload=function(){
var box3=document.getElementById("box3");
console.log(box3.offsetLeft);//70
console.log(box3.offsetTop);//86
}
</script>
</head>
<body>
<div id="box1">box1
<div id="box2">box2
<div id="box3">box3</div>
</div>
</div>
</body>
12、getBoundingClientRect()
* 作用
* 获取到元素盒模型的一些信息,得到的结果是没有单位,不包含滚动条的距离
* width 宽度(包含边框)
* height 高度(包含边框)
* left 从元素的最左边到可视区的最左边距离
* right 从元素的最右边到可视区的最左边的距离
* top 从元素的最上边到可视区的最上边的距离
* bottom 从元素的最下边到可视区的最上边的距离<style>
#box{
width:100px;
height:100px;
background:#f00;
position: absolute;
left:300px;
top:200px;
border:0px solid #000;
}
</style>
<div id="box"></div>
var box=document.getElementById("box");
console.log(box.getBoundingClientRect().width);//100
13、标签属性的操作
1.getAttribute
* 用来获取元素的属性
* 元素.getArrtibute(属性名)
*
* 如果参数是一个src或者href的话,那它取到的结果就是引号里面的值(相对地址)
* 它取不到js的自定义属性
* 它可以取到html标签的自定义属性window.onload=function(){
var box=document.getElementById("box");
var pic=document.getElementById("pic");
console.log(box.id);//box
console.log(pic['src']);//http://127.0.0.1:8020/javascript%E7%B2%BE%E5%93%81%E8%AF%BE%E7%A8%8B/%E7%AC%AC%E4%BA%94%E7%AB%A0/image/1.jpg
console.log(box.getAttribute('class'));//color
console.log(pic.getAttribute('src'));//image/1.jpg
box.index=1;
console.log(box.index);//1
console.log(box.getAttribute('index'));//null
console.log(box);
console.log(box.n);//undefined
console.log(box['n']);//undefined
console.log(box.getAttribute('n'));//kaivon
console.log(box['data-v']);//undefined
console.log(box.dataset.v);//haitang
}
</script>
</head>
<body>
<div id="box" n='kaivon' data-v="haitang"class="color">
<img id="pic" src="image/1.jpg"/>
</div>
</body>
2.setAttribute
* 设置属性
* 元素.setAttribute(attr,value);
* 两个参数必需同时出现window.onload=function(){
var box=document.getElementById("box");
box.setAttribute('id','box2');
console.log(box);
box.setAttribute('n','海棠');
console.log(box);
box.setAttribute('style','width:200px;height:100px');
console.log(box);
}
</script>
</head>
<body>
<div id="box" n='kaivon' data-v="haitang"class="color" style="width: 100px;">
<img id="pic" src="image/1.jpg"/>
</div>
</body>
3.removeAttribute
* 删除属性
* 元素.removeAttribute(属性名)<div id="box" n='kaivon' data-v="haitang"class="color" style="width: 100px;"></div>
window.onload=function(){
var box=document.getElementById("box");
box.removeAttribute('n');
console.log(box);
};
14、获取元素的宽高
* 元素.offsetWidth
* 返回元素的宽度,包含边框的
* 元素.clientWidth
* 返回元素的宽度,不包含边框
*
* 元素的高度
* 元素.offsetHeight
* 返回元素的高度,包含边框的
* 元素.clientHeight
* 返回元素的高度,不包含边框15、可视区的宽高
document.documentElement.clientWidth
document.documentElement.clientHeight
作用:可以根据可视区的宽高减去元素的宽高除以2,使元素居中显示
16、creatElement
* 作用
* 创建元素:通过标签名的形式来创建一个元素
* 语法
* document.createElement('tagName')
* createElement前面的主语只能document,其它的元素都没有这个方法
* 参数
* 标签名
* 返回值
* 返回创建的标签元素
* 注意
* 只能用来创建元素节点,不能创建文本、注释节点
* 创建后的标签可以对它进行操作17、appendChild
* 作用
* 添加元素:往父节点里在添加一个元素
* 注意:它是添加到父节点的最后面
* 语法
* 父节点.appendChild(childNode)
* 参数
* 子元素,一般为用caeateElement创建后的节点
* 返回值
* 返回创建的那个标签元素
* 注意
* 只能添加标签节点,不能添加其它节点window.onload=function(){
var btn=document.getElementById("btn");
btn.onclick=function(){
var div=document.createElement('div');
div.style.width='200px';
div.style.height='300px';
div.style.background='red';
var p=document.createElement('p');
p.innerHTML='这里是文字';
var a=document.body.appendChild(p);//返回值
console.log(a);//<p>这里是文字</p>
document.body.appendChild(div);
};
}
</script>
</head>
<body>
<input type="button" id="btn" value="创建元素"/>
</body>
18、insertBefore
* 作用
* 插入元素,把第一个参数插入到第二个参数的前面
* 语法
* 父级.insertBefore(childNode1,childNode2)
* 参数
* childNode1 要插入的元素
* chilsNod2 决定childNod1插入的位置
*
* 两个参数必需同时存在,否则就会报错
* 第二个参数如果为null或者undefined的时候,insertBefore的作用相当于appedChild
* 返回值
* 返回要插入的那个元素(第一个参数)window.onload=function(){
var ul=document.querySelector("ul");
var lis=document.querySelectorAll("li");
var newLi=document.createElement('li');
newLi.innerHTML='white';
ul.insertBefore(newLi,lis[2]);
var newLi2=document.createElement("li");
newLi2.innerHTML='black';
var result=ul.insertBefore(newLi2,lis[10]);//第二个位置不存在和没有写一样,都是appendChild的作用,在父级最后加
console.log(result);//<li>black</li>
}
</script>
<ul>
<li>red</li>
<li>green</li>
<li>blue</li>
<li>yellow</li>
<li>pink</li>
</ul>
19、removeChild
* 作用
* 移除元素,从父级里移除指定的元素
* 语法
* 父级.removeChild(childNode)
* 参数
* 要删除的子元素
* 返回值
* 返回被删除掉的那个元素window.onload=function(){
var ul=document.querySelector("ul");
var lis=document.querySelectorAll("li");
var result=ul.removeChild(lis[2]);
console.log(result);//<li>blue</li>
};
</script>
<ul>
<li>red</li>
<li>green</li>
<li>blue</li>
<li>yellow</li>
<li>pink</li>
</ul>
20、replaceChild
* 作用
* 替换元素,用第一个参数替换第二个参数
* 语法
* 父级.replaceChild(node,childNode)
* 参数
* node 要替换的元素
* childNode 被替换的元素
* 两个参数必需同时出现,不然会报错
*
* 返回值
* 返回被替换的那个元素(第二个参数)
*
* 注意
* 如果用父级里的元素去替换另一个元素
* 替换的那个元素会跑到被替换元素的位置
* 被替换的那个元素会被删掉window.onload=function(){
var ul=document.querySelector("ul");
var lis=document.querySelectorAll("li");
var newLi=document.createElement("li");
newLi.innerHTML='white';
var result=ul.replaceChild(newLi,lis[2]);
console.log(result);//<li>blue</li>
ul.replaceChild(lis[6],lis[0]);
//ul.replaceChild(lis[0]); //报错
};
</script>
<ul>
<li>red</li>
<li>green</li>
<li>blue</li>
<li>yellow</li>
<li>pink</li>
</ul>
21、cloneNode
* 作用
* 克隆一个节点
* 语法
* 要克隆的节点.cloneNode(boolean)
* 参数
* true 克隆元素和元素包含的子孙节点
* false 克隆元素但是不包含子孙节点
* 如果不写参数的话,默认为false
* 克隆只克隆html、css,js是不会被克隆的,如果克隆元素身上有js的功能,那克隆后的元素是不具备的
* 如果克隆的元素本身有id,那克隆后的元素也会有id,两个就会重名,这样的话是不符合标准,手动去改一下id
* 返回值
* 返回被克隆的节点window.onload=function(){
var box=document.getElementById("box");
var spans=document.querySelectorAll("span");
var divs=document.querySelectorAll("#box div");
//给每个span标签添加一个事件
for(var i=0;i<spans.length;i++){
spans[i].onclick=function(){
alert(this.innerHTML);
}
}
var newDiv=divs[0].cloneNode(false);
//var newDiv=divs[0].cloneNode(ture);
//var newDiv=divs[0].cloneNode();
console.log(newDiv);//<div style='color: #f00'></div>
box.appendChild(newDiv);
var blue=divs[2].cloneNode(true);
blue.id='blue1';
box.appendChild(blue);
console.log(blue);//<div id="blue1">blue</div>
};
</script>
<div id="box">
<div style='color: #f00'><span>red</span><span>green</span></div>
<div>yellow</div>
<div id="blue">blue</div>
<div>pink</div>
</div>
22、DOM操作的特性
* appendChild/insertBefore/replaceChild在操作一个已有的元素时,是将已有的元素移动,而不是复制一份进行操作(剪切)
23、留言板例子
window.onload=function(){
var text=document.getElementById("text");
var btn=document.getElementById("btn");
var list=document.getElementById("list");
btn.onclick=function(){
var val=text.value;
var li=document.createElement('li');
li.innerHTML=val;
//list.appendChild(li); //加杂在最后面
//list.insertBefore(li,list.children[0]); //加在最前面
list.insertBefore(li,list.firstElementChild);//加在最前面
//list.innerHTML+='<li>'+val+'</li>'; //加在最后面
};
};
</script>
</head>
<body>
<input type="text" id="text" value=""/>
<input type="button" id="btn" value="提交"/>
<ul id="list"></ul>
24、innerHTML与DOM操作的区别
* innerHTML
* 它会把原来的内容先清空,然后再添加新的内容,原来的内容已经没有了。只不过是新添加的内容与原来的内容长得一样而已
* DOM方法
* 会把新的内容追加到原来的内容里面,原来内容所具有的事件,依然会在window.onload=function(){
var color=document.getElementById("color");
var lis=document.getElementsByTagName("li");
for(var i=0;i<lis.length;i++){
lis[i].onclick=function(){
alert(this.innerHTML);
};
}
//innerHTML方法给color添加元素
//color.innerHTML+='<li>white</li>';
//这样上面的for循环以及点击事件就无效了,因为获取到的东西已经不存在了。
//DOM方法给color添加元素
var newLi=document.createElement("li");
newLi.innerHTML='white';
color.appendChild(newLi);
};
</script>
</head>
<body>
<ul id="color">
<li>red</li>
<li>green</li>
<li>blue</li>
<li>yellow</li>
<li>pink</li>
</ul>
25、动态获取元素以及静态获取元素的区别
* getElementsByTagName(所有的get都是动态)
* 动态获取元素,只要原来的结果有变化,这就能监听到,它会重新去获取一次元素,那这个时候原来的下标就变化了,变成新的下标 了
*
* querySlectorAll (所有的query都是静态)
* 静态获取元素,只获取一次,会把下标存下来,即使原来的结构有变化,它也不会去重新获取window.onload=function(){
var color=document.getElementById("color");
var lis=document.getElementsByTagName('li');
for(var i=0;i<lis.length;i++){
color.appendChild(lis[i]);
/*2yellow
4pink
1green
5blue
3red*/
//因为是用getElemntsByTagName,所以每一次的循环下标数都有变化
//如果是用querySelectAll公获取li的话,因为下标数已经定死了
/*1green
2yellow
3red
4pink
5blue*/
}
};
</script>
</head>
<body>
<ul id="color">
<li>2yellow</li>
<li>4pink</li>
<li>1green</li>
<li>5blue</li>
<li>3red</li>
</ul>
26、DOM操作表格
* tbody
* 表格中的tbody是可以不写的,在游览器解析的时候,会自动帮你加上
* 建议大家写的时候要加上
*
* 表格操作
* 获取表格头
* 表格.tHead
* 返回整个表格头,thead里的所有内容
* 注意:一个表格里只能有一个表格头
*
* 获取表格主体
* 表格.tBodies
* 返回的是整个表格的主体内容,是一个数组
*
* 获取表格底部
* 表格.tFoot
* 返回这个表格的底部,tfoot里的所有内容
* 注意:一个表格只有一个tfoot
*
* 获取表格行
* 表格.rows/tHead.rows/tBodies.rows/tFoot.rows
* 返回各自对应的行,是个数组
* 注意:可以设置整个行的样式
*
* 获取表格的单元格
* 行.cells
* 返回这一行的所有单元格,是个数组
* 注意:它不能对整个单元格进行操作,只能取到某一个单元格进行操作window.onload=function(){
var table=document.querySelector("table");
var head=table.tHead;
var tbody=table.tBodies;
var foot=table.tFoot;
head.style.background='red';
tbody[0].style.background='green';
foot.style.background='blue';
head.rows[0].style.color='#ccc';
tbody[0].rows[2].style.color='#f90';
foot.rows[0].style.color='#a9a';
head.rows[0].cells[0].style.fontSize='30px';
tbody[0].rows[0].cells[1].style.fontSize='40px';
foot.rows[0].cells[0].style.fontSize='50px';
};
</script>server.Sorryfor the inconvenience.
Please report this message and include the following information to us.
Thank you very much!
URL: http://www.wiz.cn/guidemap_sendimage.html?plat=x86&v=4.5.9.0&l=zh-cn&
Server: ay1405041044122256d3z
Date:2017/02/2708:33:44
Powered by Tengine
</head>
<body>
<table>
<thead>
<tr>
<th>编号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>赵四</td>
<td>男</td>
<td>50</td>
</tr>
<tr>
<td>2</td>
<td>刘能</td>
<td>男</td>
<td>53</td>
</tr>
<tr>
<td>3</td>
<td>谢广坤</td>
<td>女</td>
<td>40</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4">全是人</td>
</tr>
</tfoot>
</table>
</body>
27、DOM操作表单
* 操作表单
* 获取表单的值
* node.value
* input
* select
* textarea
*
* 给每个表单都添加了一个name属性,用这个属性去获取到相应的表单元素
*
* selectedIndex
* 获取到下拉框里内容对应的索引值,它的索引值是默认添加上去的
*
* oninput
* 只要在输入框里输入内容的时候就会触发这个事件
*
* onchange
* 当下拉框里的内容有变化的时候就会触发这个事件
*
* onsubmit
* 当表单提交的时候会触发(点击submit按钮才能触发)
* 表单.onsubmit
*
* onreset
* 当表单被重置的时候会触发(点击重置按钮才能触发)
* 表单.onreset
*
* 表单的方法
* 表单.submit() 提交表单,会触发onsubmit事件
* 表单.reset() 重置表单,会触发onreset事件
* 表单.reset() 重置表单,会触发onreset事件
window.onload=function(){
var form=document.getElementById("form");
form.btn.onclick=function(){
console.log(form.username.value);//获取到输入框里的值
console.log(form.sex.value);//获取单先框的值
console.log(form.sel.value,form.sel.selectedIndex);//获取select框里的值
//获取到checkBox的值
//console.log(form.interest[0].value);
var arr=[];
for(var i=0;i<form.interest.length;i++){
if(form.interest[i].checked){
arr.push(form.interest[i].value);
}
}
console.log(arr);
};
form.username.oninput=function(){
console.log('你有输入内容了')
};
form.sel.onchange=function(){
console.log('你选择的内容有变化了');
};
form.onsubmit=function(){
alert('你的表单要被提交了');
};
form.onreset=function(){
alert('你的表单要被重置了');
};
form.send.onclick=function(){
//form.submit();
form.reset();
};
};
</script>
</head>
<body>
<form action="#" id="form">
<input type="text" name="username" value=""/>
<p>
性别
<input type="radio" name="sex" value="男"/>男
<input type="radio" name="sex" value="女"/>女
</p>
<p>
兴趣
<input type="checkbox" name="interest" value="吃饭"/>吃饭
<input type="checkbox" name="interest" value="睡觉"/>睡觉
<input type="checkbox" name="interest" value="打豆豆"/>打豆豆
</p>
<p>
来自于
<select name="sel">
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="广州">广州</option>
</select>
</p>
<textarea name="text" rows="10" cols="30"></textarea>
<input type="button" name="btn" value="点击"/>
<input type="submit" name="sub" value="提交"/>
<input type="reset" name="res" value="重置"/>
<input type="button" name="send" value="发送"/>
</form>
增加事件: onmouseover 当鼠标放在上面
onmouseout 当鼠标放开
通过样式该显示
xx.onclick=yy.onclick=function(){}
return 是否在作用于内是否有效果