DOM
简介
文档对象模型(简称DOM)是针对HTML和XML文档的一个API(应用程序编程接口)
W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容,结构和样式。
DOM描绘了一个层次化的节点树,允许开发人员添加,移除,修改页面的某一部分。
DOM可以将任何HTML或XML文档描绘成一个由多层节点构成的结构。
节点分为几种不同的类型,每种类型分别表示文档中不同的信息或标记。每个节点拥有各自的特点,数据和方法,(注释没有操作方法)另外也有与其他节点存在某种关系。
节点之间的关系构成了层次,所有页面标记则表现为一个以特定节点为根节点的树形结构。
我们获取的DOM元素都是一个对象,所有称为文档对象模型
DOM树
窗口 window ;
文档 document(为window子对象),一个页面就是一个文档;
元素 element 页面中所有的标签都是元素;
节点 node 页面中的所有内容都是节点(标签,属性,文本,注释等)
DOM不能在node环境下运行,在浏览器环境下运行
<div id="one"></div>
var one = document.getElementById('one');
//document 是 HTMLDocument实例对象,是window的属性
//one 是 HTMLDivElement实例对象
1. Node.prototype
1.1Node类型:
javascript中所有的节点类型都继承自Node类型,所有节点类型都共享着相同的基本属性和方法。
1.2属性:
一般节点至少拥有nodeType(节点类型),nodeName(节点名称),nodeValue(节点值)三个基本属性。
基本属性
-
nodeType
表示节点类型
文档节点Document(指向文档树)–> 9;
元素节点Element -->1;
文本节点TextNode(包括文字,空格,换行等) -->3;
注释节点Comment–> 8实际开发中,节点操作主要操作的是元素节点。
document 是Document构造函数的实例
document.body是Element构造函数的实例
document.body.firstChild 是TextNode构造函数的实例 -
nodeName
节点名,该属性取决于节点类型,如果是元素类型,值为元素的标签名
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> //document文档 console.log(document.nodeType); //指向HTML根元素 9 //element标签 var ele=document.createElement('div'); console.log(ele.nodeType); //1 console.log(ele.nodeName); //div //textnode 文本类型 var text=document.createTextNode('今天天气很好,小没哭了'); console.log(text.nodeType); //3 //comment 注释 var com=document.createComment('这是一行注释'); console.log(com.nodeType); //8 </script> </body> </html>
-
nodeValue
该属性取决于节点类型,如果是元素类型,值有null(常用于表单元素,有value的元素)
节点层级
-
childNodes
得到元素
所有的子节点
,包含元素节点和文本节点(空格,换行)
保存一个NodeList对象,NodeList是一种类数组对象用来保存一组有序的节点,NodeList是基于DOM结构动态执行查询的结果,DOM结构变化可以自动反应到NodeList对象中。访问时可以通过中括号访问,也可以通过item()方法访问。可以使用slice方法将NodeList转换为数组var arr = Array.prototype.slice.call(nodes,0);
<ul> <li>1</li> <li>1</li> <li>1</li> </ul> var ul=document.querySelector('ul'); console.log(ul.childNodes.length); // 7 有四个子节点为文本节点(换行)
若只想获得里面的元素节点,需要专门处理,所以一般不使用childNodes
for(var i=0; i<ul.childNodes.length; i++){ if (ul.childNodes[i] . nodeType ===1) { //保证子节点为元素节点 console.log(ul.childNodes[i]; } }
可以使用children,获取所有的子元素节点
console.log(ul.children)
-
children
返回所有的子元素节点
下拉菜单
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style-type: none;
}
a {
text-decoration: none;
font-size: 14px;
}
.nav {
margin: 100px;
}
.nav>li {
position: relative;
float: left;
width: 80px;
height: 41px;
text-align: center;
}
.nav li a {
display: block;
width: 100%;
height: 100%;
line-height: 41px;
color: #333;
}
.nav>li>a:hover {
background-color: #eee;
}
.nav ul {
display: none;
position: absolute;
top: 41px;
left: 0;
width: 100%;
border-left: 1px solid #FECC5B;
border-right: 1px solid #FECC5B;
}
.nav ul li {
border-bottom: 1px solid #FECC5B;
}
.nav ul li a:hover {
background-color: #FFF5DA;
}
</style>
<ul class="nav">
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
</ul>
<script>
var nav = document.querySelector('.nav');
var lis = nav.children;
for (var i = 0; i < lis.length; i++) {
lis[i].onmouseover = function() {
this.children[1].style.display='block';
}
lis[i].onmouseout = function() {
this.children[1].style.display='none';
}
}
</script>
-
parentNode
指向文档树中的父节点。包含在childNodes列表中所有的节点都具有相同的父节点,每个节点之间都是同胞/兄弟节点。
得到的是距离元素最近的父级节点,若找不到父节点则返回null。 -
previousSibling
前一个兄弟节点
-
previousElementSibling
下一个兄弟元素节点,没有返回null
-
nextSibling
下一个兄弟节点
-
nextElementSibling
上一个兄弟元素节点,没有返回null
-
firstChild
childNodes列表中的第一个节点(可能为元素节点,文本节点或其他节点)
-
firstElementChild
返回第一个子元素节点,找不到则返回null
有兼容性问题,IE9以上才支持实际开发中的写法,在没有兼容性问题的情况下返回第一个和最后一个子元素节点
console.log(ul.children[0]); console.log(ul.children[ul.children.length-1]);
-
lastChild
返回最后一个子节点
-
lastElementChild
返回最后一个子元素节点,找不到则返回null
有兼容性问题,IE9以上才支持 -
ownerDocument
指向表示整个文档的文档节点。任何节点都属于它所在的文档,任何节点都不能同时存在于两个或更多个文档中。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="a1">今天天气不好,小没哭了</div><ul id="myul"><li>《夜的第七章》</li><li>《维也纳》</li><li>《喜羊羊与灰太狼》</li> </ul> <script> //属性 var myul=document.getElementById('myul'); console.log(myul.childNodes.length); //3 会识别空白节点,可能会导致节点数不准确 console.log(myul.children.length); //3 返回所有element类型的子节点(不会识别空白节点) var lis=myul.children; lis[0].style.backgroundColor='red'; //将第一个子节点背景颜色变为红色 console.log(lis[0].parentNode); //指向该节点的父节点 console.log(myul.previousSibling); //该节点的上一节点 会算上空白节点 myul.previousSibling.style.backgroundColor='blue'; //该节点父节点的上一节点 console.log(myul.nextSibling); myul.nextSibling.style.backgroundColor='pink';//该节点的下一节点 console.log(myul.firstChild); //返回列表中第一个子节点 console.log(myul.lastChild); //返回列表中最后一个子节点 console.log(myul.ownerDocument); //返回document </script> </body> </html>
1.3方法:
-
createElement()
创建元素节点
创建节点后通常需要添加节点(appendChild()) -
hasChildNodes()
在包含一个或多个子节点的情况下返回true
-
appendChild()
node.appendChild(child) ;node为父节点,child为子节点
将新创建的节点child添加进node子节点的末尾
。<ul> <li>123</li> </ul> <script> var li=document.createElement('li'); var ul=document.querySelector('ul'); ul.appendChild(li); //将新增的li节点添加到ul的子节点的末尾 </script>
向childNodes列表末尾添加一个节点。返回新增的节点。关系更新如果参数节点已经为文档的一部分,位置更新而不插入,dom树可以看做是由一系列的指针连接起来的,任何DOM节点不能同时出现在文档中的多个位置
-
insertBefore()
node.insertBefore(child,指定元素);
第一个参数:要插入的节点;第二个参数:作为参照的节点;
将创建的节点插入指定元素的前面
。
如果第二个参数为null将会将该节点追加在NodeList后面在页面中添加一个新的元素:1.创建元素;2.添加元素
发布留言案例
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
}
textarea {
width: 200px;
height: 100px;
border: 1px solid pink;
outline: none;
resize: none;
}
ul {
margin-top: 50px;
}
li {
width: 300px;
padding: 5px;
background-color: rgb(245, 209, 243);
color: red;
font-size: 14px;
margin: 15px 0;
}
</style>
<textarea name="" id="" cols="30" rows="10">123</textarea>
<button>发布</button>
<ul>
</ul>
<script>
//点击按钮就动态创建一个li,添加到ul里
//创建li的同时,把文本域里的值使用innerHTML赋值给li
//要将留言显示在后面就使用appendChild();将留言显示在前面就使用insertBefore()
var btn=document.querySelector('button');
var text=document.querySelector('textarea');
var ul=document.querySelector('ul');
btn.onclick=function(){
if(text.value==''){
alert('请输入内容');
return false;
}else{
//创建元素
var li=document.createElement('li');
//赋值
li.innerHTML=text.value;
//添加元素
ul.insertBefore(li,ul.children[0]);
}
}
</script>
-
replaceChild()
第一个参数:要插入的节点;第二个参数:要替换的节点;
要替换的节点将由这个方法返回并从文档树中被移除,同时由要插入的节点占据其位置 -
removeChild()
node.removeChild(child) 将node 节点中的一个子节点child节点移除
一个参数,即要移除的节点。
移除的节点将作为方法的返回值。其他方法,任何节点对象都可以调用。点击按钮依次删除里面的孩子
<ul> <li>大哥</li> <li>二哥</li> <li>三弟</li> </ul> var ul=document.querySelector('ul'); var btn=document.querySelector('button'); btn.onclick=function(){ if(ul.children.length==0){ //当子节点删除完后 this.disabled=true; // 禁用按钮 }else{ ul.removeChild(ul.children[0]);//删除第一个子节点 } }
删除发布留言案例
li a{
float: right;
text-decoration: none;
}
<textarea name="" id="" cols="30" rows="10">123</textarea>
<button>发布</button>
<ul>
</ul>
<script>
//点击按钮就动态创建一个li,添加到ul里
//创建li的同时,把文本域里的值使用innerHTML赋值给li
//要将留言显示在后面就使用appendChild();将留言显示在前面就使用insertBefore()
var btn=document.querySelector('button');
var text=document.querySelector('textarea');
var ul=document.querySelector('ul');
btn.onclick=function(){
if(text.value==''){
alert('请输入内容');
return false;
}else{
//创建元素
var li=document.createElement('li');
//赋值
li.innerHTML=text.value+"<a href='javascript:;'>删除</a>"; //使用a时,防止链接跳转可以将href设为javascccript:;即可
//添加元素
ul.insertBefore(li,ul.children[0]);
//删除元素
var as=document.querySelectorAll('a');
for(var i=0;i<as.length;i++){
as[i].onclick=function(){
ul.removeChild(this.parentNode); //删除整个li(a的父节点),ul的子节点
}
}
}
}
</script>
动态生成表格
<style>
table {
width: 500px;
margin: 100px auto;
border-collapse: collapse;
text-align: center;
}
td,
th {
border: 1px solid #333;
}
thead tr {
height: 40px;
background-color: #ccc;
}
</style>
<table cellspacing="0">
<thead>
<tr>
<th>姓名</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
//数据
var datas=[
{
name:'xiaoming',
subject:'javascript',
score:100
},
{
name:'xiaohong',
subject:'javascript',
score:98
},
{
name:'xiaobai',
subject:'javascript',
score:95
},
{
name:'xiaohei',
subject:'javascript',
score:90
},
{
name:'xiaohuang',
subject:'javascript',
score:101
},
]
//创建行
var tbody=document.querySelector('tbody');
for(var i=0;i<datas.length;i++){ //行
//创建tr行
var tr=document.createElement('tr');
tbody.appendChild(tr);
//创建单元格td,单元格数量取决于每个数据对象中属性的个数
for(var k in datas[i]){ //列
//创建单元格(与数据有关)
var td=document.createElement('td');
tr.appendChild(td);
//k表示属性值,obj[k]表示属性值
td.innerHTML=datas[i][k];
}
var td=document.createElement('td');
td.innerHTML='<a href="javascript:;">删除</a>';
tr.appendChild(td);
}
//删除数据操作
var as=document.querySelectorAll('a');
for(var i=0;i<as.length;i++){
as[i].onclick=function(){
tbody.removeChild(this.parentNode.parentNode);
}
}
</script>
-
cloneNode()
node.cloneNode(false/true) 克隆(赋值)节点,(要想在页面显现出来需要添加节点)
用于创建调用这个方法的节点的一个完全相同的副本。
括号中参数为布尔类型参数为true时,表示深拷贝,即复制节点以及整个子节点数(节点内容)。
括号中参数为false或为空的时候,表示浅拷贝,只复制节点本身。
该方法不会复制添加到DOM节点中的JavaScript属性,例如事件处理程序等。该方法只复制特定,子节点,其他一切都不复制。但是IE中可以复制,建议标准相同,在复制之前,移除所有事件处理程序。 -
normalize()
处理文档树中的文本节点,由于解析器的实现或DOM操作等原因,可能会出现文本节点不包含文本,或者接连出现两个文本节点,当在某个节点上调用了该方法,会
删除空白节点
,会找到相邻的两个文本节点,并将他们合并为一个文本节点。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="a1">今天天气不好,小没哭了</div><ul id="myul"><li>《夜的第七章》</li><li>《维也纳》</li><li>《喜羊羊与灰太狼》</li> </ul><div>哈哈哈</div> <script> //方法 console.log(myul.hasChildNodes()); //包含一个或多个子节点返回true,空节点返回false //往myul中添加一个子元素li,内容为《听妈妈的话》 //1.创建文本节点 var t=document.createTextNode('《听妈妈的话》'); //2.创建ele节点 var e=document.createElement('li'); //3.将文本放到ele节点中 e.appendChild(t); //向li中添加一个节点 //4.将ele放到ul中 myul.appendChild(e); //向ul中末节点中添加一个节点 //1.创建文本节点 var t=document.createTextNode('《猪猪侠》'); //2.创建ele节点 var e=document.createElement('li'); //3.将文本放到ele节点中 e.appendChild(t); //将ele放到ul中lis[1]的前面 myul.insertBefore(e,lis[1]); //将第一个参数放到第二个参数的前面 //1.创建文本节点 var t=document.createTextNode('《把啦啦小魔仙》'); //2.创建元素节点 var e=document.createElement('li'); //3.将文本放到元素节点中 e.appendChild(t); //替换到其中一个节点 myul.replaceChild(e,lis[2]); //将第一个参数替换第二个参数(替换时原节点被替换时样式同时也会被替换,新节点没有原节点的样式) //移除一个子节点 myul.removeChild(lis[0]); var a1=document.getElementById('a1'); var a2=a1.cloneNode(); //若有参数的情况下,默认为浅拷贝,不拷贝内容,只拷贝标签 //若希望拷贝内容,则执行值为true,变成深拷贝,将所有内容进行拷贝 //需要注意事件,因为在主流浏览器中事件不会被拷贝,但在IE浏览器中,事件会被拷贝,所有在拷贝有事件的节点时,建议先移除事件 console.log(a2); var t=document.createTextNode('hello'); a1.appendChild(t); console.log(a1.childNodes.length) //2 var t=document.createTextNode('hello'); a1.appendChild(t); console.log(a1.childNodes.length) //3 a1.normalize(); //删除空白节点 console.log(a1.childNodes.length) //1 删除空白节点,相邻的两个文本节点合并为一个文本节点。 </script> </body> </html>
2.Document.prototype
1.1Document类型
Javascript通过使用Document类型表示文档。在浏览器中,document对象是HTMLDocument的一个实例,表示整个HTML页面。document对象是window对象的一个属性,因此可以直接调用。HTMLDocument继承自Document。
文档子节点可以继承Node中所有的属性和方法
1.2属性:
-
documentElement
始终指向HTML页面中的元素。
document.documentElement 获取HTML元素对象
-
body
直接指向元素
document.body 获取body元素对象
-
doctype
返回版本信息,访问<!DOCTYPE>, 浏览器支持不一致,很少使用
-
title
获取文档的标题
-
URL
取得当前页面完整的URL
-
domain
取得域名,并且可以进行设置,在跨域访问中经常会用到。
-
referrer
取得链接到当前页面的那个页面的URL,即来源页面的URL。
-
images
获取所有的img对象,返回HTMLCollection类数组对象
-
forms
获取所有的form对象(表单元素),返回HTMLCollection类数组对象
-
links
获取文档中所有带href属性的a元素
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> //document //属性 console.log(document.documentElement); //获取HTML元素 console.log(document.body); //获取body元素 console.log(document.doctype); //版本信息 console.log(document.title); //文档标题 console.log(document.URL); //返回当前页面所在网址 console.log(document.domain); //返回域名 console.log(document.referrer); //当前页面从哪个页面跳转而来 console.log(document.forms); //获取所有当前页面的表单元素,返回类数组对象 console.log(document.images); //获取所有img对象,返回类数组对象 console.log(document.links); //获取文档所有带href属性的a标签 </script> </body> </html>
1.3方法
获取元素
-
getElementById()
参数为要取得元素的ID,如果找到返回该元素,否则返回null。
如果页面中多个元素的ID值相同,只返回文档中第一次出现的元素。
如果某个表单元素的name值等于指定的ID,该元素也会被匹配。
返回值为一个元素对象。 -
getElementsByTagName()
参数为要取得元素的标签名,返回包含零个或者多个元素的NodeList。
可以通过[index/name],item(),namedItem(name)访问。
若获取的元素为空,则返回一个空的伪数组。
返回的是获取过来的元素对象的集合,一位数组的形式存储。 -
element.getElementByTagName()
获取某个元素内部所有指定标签名的子元素。
父元素必须是 指定的单个元素(不能是伪数组),获取的结果不包括父元素
<ol id='ol'>
<li> ol1</li>
<li> ol2</li>
<li> ol3</li>
</ol>
<ul>
<li> ul1</li>
<li> ul2</li>
<li> ul3</li>
</ul>
<script>
var ol=document.getElementsByTayName('ol');
console.log(ol.getElementByTagName('li')); //错误, ol 为一个伪数组,不能作为父元素
console.log(ol[0] .getElementByTagName('li'));
var ol=document.getElementById('ol');
console.log(ol.getElementByTagName('li')); //正确,可以使用id元素对象作为父元素
</script>
-
getElementsByName()
参数为元素的name,返回符合条件的NodeList (常用于表单元素)
-
getElementsByClassName()
参数为一个字符串,可以由多个空格隔开的标识符组成。当元素的class属性值包含所有指定的标识符时才匹配。HTML元素的class属性值是一个以空格隔开的列表,可以为空或包含多个标识符。
根据类名获得某些元素的集合。 -
querySelector(‘选择器名’)
H5新增获取元素的方法。
选择器名要加上符号
根据指定选择器返回第一个元素对象。var ols=document.querySelector(‘#ol’); var lis=document.querySector('li');
-
querySelectorAll(‘选择器名’)
H5新增获取元素的方法。
根据指定选择器返回所有元素对象。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <p class="blues">今天天气好,小没开心的</p> <div>今天天气好,小没开心的</div> <b class="blues">今天天气好,小没开心的</b> <p>今天天气好,小没开心的</p> <ul> <li>今天天气好,小没开心的</li> <li id="red">今天天气好,小没开心的</li> <li>今天天气好,小没开心的</li> </ul> <script> //文档从上往下加载,因此要先有标签,要将script写到标签下面 //方法 //查找元素 var red=document.getElementById('red'); //通过id查找元素 red.style.backgroundColor='red'; var ps=document.getElementsByTagName('p'); //通过标签名查找元素,有多个p标签,所有ps为一个类数组 var ps_len=ps.length; for(var i=0;i<ps_len;i++){ ps[i].style.fontSize='24px'; //将p标签内的字体大小设置为24px } var blues=document.getElementsByClassName('blues'); //通过类名查找元素 var blues_len=blues.length; for(var i=0;i<blues_len;i++){ blues[i].style.color='blue'; } //document.getElementsByName() 返回符合名字的类数组 常用于表单元素 </script> </body> </html>
3.Element.prototype
3.1Element类型
所有的HTML元素都由HTMLElement类型表示,或者其子类型表示。每个HTML元素都应具有如下一些属性以及html元素特有的属性。
id 元素在文档中的唯一标识符
title 有关元素的附加说明信息
className 与元素class特性对应
src img元素具有的属性
alt img元素具有的属性
lang 元素内容的语言代码,很少使用!
dir 语言方向,ltr,rtl 左到右,右到左
<button id="ldh">刘德华</button>
<button id="zxy">张学友</button>
<img src="images/ldh.jpg" alt="" title='刘德华'>
<script>
var ldh=document.getElementById('ldh');
var zxy=document.getElementById('zxy');
var img=document.getElementsByClassName('img');
ldh.onlick=function(){
img.src='images/ldh.jpg';
img.title='刘德华'
}
zxy.onclick=function(){
img.src='images/zxy.jpg';
img.title='张学友'
}
</script>
分时问候案例
<img src="shangwu.jpg" alt="">
<div>上午好</div>
<script>
var img=document.querySelector('img');
var div=document.querySelector('div');
var date=new Date();
var h=date.getHours();
if(h<12){
img.src='images/shangwu.jpg';
div.innerHTML='上午好哦'
}else if(h<16){
img.src='images/xiawu.jpg';
div.innerHTML='下午好哦'
}else{
img.src='images/wanshang.jpg';
div.innerHTML='晚上好哦'
}
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="a1"></div>
<img src="#" alt="" id="i">
<script>
var a1=document.getElementById('a1');
console.log(a1.id); //返回id
a1.className='red';
a1.title='标题';
var i=document.getElementById('i');
i.src=''; //动态修改一个图片的地址
</script>
</body>
</html>
className 更改元素样式,会直接覆盖原来类名设置的样式
若保留原来类名的样式,同时写上两个类名,用空格隔开。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
width: 200px;
height: 200px;
background-color: pink;
}
.change{
width: 300px;
height: 300px;
background-color: red;
}
</style>
</head>
<body>
<div>className</div>
<script>
var test=document.querySelector('div');
test.onclick=function(){
this.className='change'; //将当前类名修改为change,从而改变元素的样式
}
</script>
</body>
</html>
密码框验证
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
width: 600px;
margin: 100px auto;
}
.message{
display: inline-block;
font-size: 12px;
color: #999;
background: url(images/mess.png) no-repeat left center;
padding-left: 20px;
}
.wrong{
color: red;
background-image: url(images/wrong.png);
}
.right{
color: green;
background-image: url(images/right.png);
}
</style>
</head>
<body>
<div class="register">
<input type="password" class="inp">
<p class="message">请输入6-16位密码</p>
</div>
<script>
//首先判断的事件是表单失去焦点
//如果输入正确则提示正确,颜色变为绿的 图标变化
//如果输入的不是6到16位,则颜色变为红的 图标变化
//样式变化多,使用className修改样式
//获取元素
var inp=document.querySelector('.inp');
var message=document.querySelector('.message');
//注册事件
inp.onblur=function(){
if(this.value.length<6 || this.value.length>16){
message.className='message wrong';
message.innerHTML='您输入的位数不对,应在6-16位'
}else{
message.className='message right';
message.innerHTML='输入正确'
}
}
</script>
</body>
</html>
每个元素都有一个或者多个特性,这些特性的用途是给出相应元素或内容的附加信息。可以通过属性访问到该属性对应的值,特性的名称是不区分大小写的
3.2方法
-
getAttribute(‘属性名’)
取得自定义属性
参数为实际元素的属性名,class,name,id,title,lang,dir一般只有在取得自定义特性值的情况下,才会用该方法。大多数直接使用属性进行访问,比如style,onclick -
setAttribute(‘属性名’ , ‘值’)
设置属性dom.className = "one" dom.setAttribute("className","one");
两个参数,第一个参数为要设置的特性名,第二个参数为对应的值。如果该值存在,替换。
使用自定义属性的目的:为了保持并使用数据。有些数据可以保存到页面中而不用保存到数据库中。
设置H5自定义属性:
H5规定自定义属性以data-开头作为属性名并赋值;
在html标签中:
<标签 data-名=‘值’></标签>
在js中:
element.setAttribute(‘属性名’,‘属性值’)
获取H5自定义属性值:
js:使用getAttribute获取属性值
element.getAtribute(' 属性名');
H5新增方法(只能获取以data-开头的自定义属性的值,有兼容性问题,需要ie11以上支持) :
element.dataset. data-后的属性名
element.dataset[' data-后的属性名 ']
若属性名中data-后面的部分里含有多个 - 连接单词,则H5获取属性值时需要使用驼峰命名法
//dataset表示一个集合,里面存放了所有以data开头的自定义属性。
<div data-index="2" data-list-name="andy"></div>
<script>
var div=document.querySelector('div');
div.setAttribute('data-time',20);
div.getAttribute('data-index');
div.getAttribute('data-list-name');
div.dataset.index;
div.dataset['index'];
div.dataset.listName;
div.dataset['listName'];
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="a1"></div>
<script> //放在HTML代码下方
//获取html属性的方式
var a1=document.getElementById('a1');
console.log(a1.id)
console.log(a1.getAttribute('id'));
//设置HTML属性的方式
a1.className='red';
a1.setAttribute('class','blue');
</script>
</body>
</html>
-
removeAttribute()
移除指定的特性
attributes属性,其中包含了一个NamedNodeMap,与NodeList类似 -
getNamedItem(name)
返回nodeName属性等于name的节点,再访问nodeValue
-
removeNamedItem(name)
从列表中删除nodeName属性等于name的值
<script>
//删除HTML元素属性
a1.removeAttribute('class')
console.log(a1.attributes) //包含所有属性的类数组对象
var attrs=a1.attributes;
console.log(attrs[0]);
console.log(attrs.getNamedItem('id').nodeValue);
// removeNamedItem(name); //删除属性
var a =document.createAttribute('class');
a.nodeValue='red';
</script>
-
setNamedItem(attrNode)
向列表中添加一个节点
var attr=document.createAttribute(”title“); attr.nodeValue=”test“; btn.attributes.setNamedItem(attr);
-
item(index)
返回位于数字index位置处的节点
-
document.createElement()
创建元素
参数为要创建元素的标签名。该标签名在HTML中不区分大小写,但是在XML中区分大小写
<script>
//添加属性的第三种方式 向列表中添加一个节点
a1.attributes.setNamedItem(a);
//创建元素
var p=document.createElement('p');
var t=document.createTextNode('今天天气不好,小没哭了');
p.appendChild(t);
a1.appendChild(p);
a1.style.backgroundColor='pink';
a1.onclick=function(){ //onclick点击事件
alert('hello');
}
</script>
特殊特性
-
style
通过getAttribute()访问时,返回的style特性值中包含的是CSS文本,而通过属性来访问返回一个对象,由于style属性是用于以编程方式访问元素样式的,因此并没有直接映射到style特性。
样式名采用驼峰命名法,如backgroundColor
修改style样式的操作后产生的是行内样式,权重较高。更改元素属性的样式有两种方法:
element.style 在样式较少或功能简单的情况下使用
element.className 适合样式较多或功能复杂的情况点击元素改变背景颜色
<style> div{ width: 300px; height: 300px; background-color: pink; } </style> <div></div> <script> var div=document.querySelector('div'); div.onclick=function(){ div.style.backgroundColor='green'; } </script>
淘宝关闭二维码案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box{
position: relative;
width: 74px;
height: 88px;
border: 1px solid #ccc;
margin: 100px auto;
font-size: 12px;
text-align: center;
color: #f40;
display: block;
}
.box img{
width: 60px;
margin-top: 5px;
}
.close-btn{
position: absolute;
top: -1px;
left: -16px;
width: 14px;
height: 14px;
border: 1px solid #ccc;
line-height:14px;
font-family: Arial;
cursor: pointer;
}
</style>
</head>
<body>
<div class="box">
淘宝二维码
<img src="images/taobao.png" alt="">
<i class="close-btn">×</i>
</div>
<script>
var btn=document.querySelector('.close-btn');
var box=document.querySelector('.box');
btn.onclick=function(){
box.style.display='none';
}
</script>
</body>
</html>
循环精灵图案例
<div class="box">
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<script>
var lis=document.querySelectorAll('li');
for(var i=0;i<lis.length;i++){
var index=i*44; //每个图标向下移动44px
lis[i].style.backgroundPosition='0 -'+index+'px';
}
</script>
-
onclick
类似的事件处理程序,通过getAttribute()访问时,返回相应代码字符串;访问onclick属性时,返回一个javascript函数
3.3属性
-
children
类似于childNodes,返回NodeList对象,但是该对象中仅包含Element对象 (不包含空格)
-
firstElementChild
第一个孩子元素节点
-
lastElementChild
最后一个孩子元素节点
-
nextElementSibling
下一个兄弟元素节点
-
previousElementSibling
上一个兄弟元素节点
-
childElementCount
子元素的数量,返回值和children.length值相等元素内容
-
innerHTML
返回元素内容,包括html标签,(只能解析HTML标签),同时保留空格和回车。
W3C标准。
可读写,可以获取元素中的内容,可以为元素赋值。
适用于div等普通元素,不适用于获取和修改表单元素的内容,表单元素需要使用value属性。在使用时需要注意安全性问题,若给了一些不是HTML标签的内容,可能会造成页面内容的紊乱。
数据是服务器返回的内容,一定要进行检测 -
innerText
元素内部的文本,去除回车和换行。
为标准。
可读写,可以获取元素中的内容,可以为元素赋值。 -
textContent
元素内部的文本,不去除空格和回车
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="a1"></div>
<ul id="u1">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<div id="a2">哈哈哈哈
<span> 哈哈哈 </span>
</div>
<script>
var u1=document.getElementById('u1');
var childs=u1.children; //只包含父元素中的Element对象(不包含空格)
u1.firstElementChild.style.backgroundColor='yellow'; //设置第一个子元素的样式
u1.lastElementChild.style.backgroundColor='blue'; //设置最后一个子元素的样式
console.log(childs);
console.log(u1.nextElementSibling); //下一个兄弟元素
u1.nextElementSibling.style.backgroundColor='red';
u1.previousElementSibling.style.fontSize='24px'; //上一个兄弟元素
//ul子元素的个数
console.log(u1.childElementCount);
console.log(u1.children.length);
console.log(u1.childNodes.length); //不准确,包含空白节点
var a2=document.getElementById('a2');
//获取元素内容
console.log(a2.innerHTML); //哈哈哈哈
//<span>哈哈哈</span> 保留HTML标签,保留回车和换行
console.log(a2.innerText); // 哈哈哈哈 哈哈哈 不识别HTML标签 不保留回车和换行
//给元素赋值
a2.innerHTML='<p>今天天气不好</p>';//设置a2元素内容,可以解析标签
a2.innerText='<p>今天天气不好</p>'; //不会解析标签,原封不动,作为文本显示,去除回车和换行
a2.textContent='<p>今天天气不好</p>';//显示文本,不去除回车和换行
</script>
</body>
</html>
3.4 表单元素属性
type ,value ,checked ,selected ,disabled
<button>按钮</button>
<input type="text" value="输入内容">
<script>
var btn=document.querySelector('button');
var inp=document.querySelector('input');
btn.onclick=function(){
inp.value='我被点击啦';
//innerHTML用于div等普通盒子内容,要想修改表单元素内容,需要修改元素的value属性。
// btn.disabled=true;
this.disabled=true; //this指向事件函数的调用者
//表单被禁用,不能再点击 disabled
}
显示隐藏的密码
<!-- 点击按钮将密码框切换为文本框,显示密码。 -->
<!-- 利用flag变量,判断flag的值,若为1则切换为文本框,将flag设置为0,为0则将文本框切换为密码框,将flag切换为1. -->
<div class="box">
<label for="">
<img src="images/close.png" alt="">
</label>
<input type="password" name="" id="">
</div>
<script>
var inp=document.querySelector('input');
var img=document.querySelector('img');
var flag=0;
img.onclick=function(){
if(flag==0){
inp.type='text';
flag=1;
img.src='images/open.png'
}else{
inp.type='password';
flag=0;
img.src='images/close.png'
}
}
</script>
显示和隐藏文本框内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
input{
color: #999;
}
</style>
</head>
<body>
<input type="text" value="手机">
<script>
//获取元素
var text=document.querySelector('input');
//注册事件 获取焦点
//获取焦点 当内容为默认时 默认文字消失
text.onfocus=function(){
if(text.value==='手机'){
this.value='';
}
this.style.color='#333'
} //获取焦点时使文字颜色变深
//失去焦点 当内容为空时,恢复默认内容
text.onblur=function(){
if(this.value=== ''){
this.value='手机';
}
this.style.color='#999'
}
</script>
</body>
</html>
4.Text.prototype
4.1Text类型(文本类型)
文本节点,包含的是可以按照字面解释的纯文本内容。
-
length //文本长度
-
appendData(text) //追加文本
-
deleteData(beginIndex,count) //删除文本
-
insertData(beginIndex,text) //插入文本
-
replaceData(beginIndex,count,text) //替换文本
-
splitText(beginIndex) //从beginIndex位置将当前文本节点分成两个文本节点
-
document.createTextNode(text) //创建文本节点,参数为要插入节点中的文本
-
substringData(beginIndex,count) //从beginIndex开始提取count个子字符串
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> var text=document.createTextNode('hello'); //创建文本 console.log(text.length); text.appendData(' xiaoming'); //hello xiaoming 追加文本 console.log(text); text.deleteData(0,6); //删除文本(开始位置,删除个数) console.log(text); text.replaceData(0,8,'xiaohong'); //xiaohong 替换文本(开始位置,替换个数,替换文字) console.log(text); var res=text.splitText(4); //从beginIndex位置将当前文本节点分成两个文本节点 console.log(res); //hong console.log(text); //xiao console.log(text.substringData(0,3)); //xia 从第一个位置开始提取第二个参数个子字符串 </script> </body> </html>
4.2comment类型(注释类型)
<div id = "myDiv"><! --a comment--> < /div >
<! --a comment–> Comment类型
操作元素总结
- 操作元素内容
innerText
innerHTML - 操作常见元素属性
src , href , title , alt 等 - 操作表单元素属性
type , value , disabled 等 - 操作元素样式属性
element.style
className - 获取元素属性值
element.属性 获取元素自带属性的值
element.getAttribute(‘属性’) 用于获取自定义的属性 - 设置属性值
element.属性=‘值’ 设置自带属性
element.setAttribute(‘属性’ , ‘值’); 主要用于修改自定义属性
使用自定义属性的目的:为了保持并使用数据。有些数据可以保存到页面中而不用保存到数据库中。 - 移除属性
element.removeAttribute(‘属性’)
三种创建元素方式及区别
-
document.write()
创建元素,若页面文档流加载完毕,再调用这句话会导致页面重绘<button>点击</button> <p>abc</p> <div class="inner"></div> <div class="create"></div> <script> var btn=document.querySelector('button'); //当页面流加载完毕,点击按钮时创建元素,页面重绘,原来的页面内容消失,只留下新创建的元素 btn.onclick=function(){ document.write('<div>123<div>'); } </script>
-
innerHTML
var inner=document.getElementsByClassName('inner'); //拼接字符串方式,效率最低 for(var i=0;i<100;i++){ inner.innerHTML+='<a href="#">百度</a>' } //数组方式拼接字符串,效率高 var arr = []; for (var i = 0; i <= 100; i++) { arr.push('<a href="#">百度</a>'); } inner.innerHTML = arr.join('');
-
document.createElement()
var create=document.querySelector('.create'); for(var i=0;i<=100;i++){ var a=document.createElement('a'); create.appendChild(a); }
innerHTML是将内容写入某个DOM节点,不会导致页面全部重绘
innerHTML创建多个元素效率更高(不采用拼接字符串方式,而是采用数组形式拼接),结果稍微复杂
createElement() 创建多个元素效率较低,但是结构清晰
案例一:用户名显示与隐藏
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box{
width: 600px;
height: 100px;
margin: 100px auto;
}
input{
color: #999;
padding-left: 10px;
border: 1px solid #999;
height: 20px;
outline: none;
font-size: 12px;
}
</style>
</head>
<body>
<div class="box">
<input type="text" id="text" value="邮箱/ID/手机号">
<input type="text" id="password" value="密码">
</div>
<script>
var text=document.getElementById('text');
var pas=document.getElementById('password');
text.onfocus=function(){
this.style.color='#333';
this.style.border='1px solid pink';
if(this.value==="邮箱/ID/手机号"){
this.value='';
}
}
text.onblur=function(){
this.style.border='1px solid #999';
if(this.value===''){
this.value="邮箱/ID/手机号";
this.style.color='#999';
}
}
pas.onfocus=function(){
this.style.color='#333';
this.type='password';
this.style.border='1px solid pink';
if(this.value==="密码"){
this.value='';
}
}
pas.onblur=function(){
this.style.border='1px solid #999';
if(this.value===''){
this.value="密码";
this.type='text';
this.style.color='#999';
}
}
</script>
</body>
</html>
案例二:开关灯
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
#box{
height: 600px;
width: 100%;
/* background-color: black; */
}
button{
margin: 10px 0 0 10px;
padding: 0 10px;
}
</style>
</head>
<body>
<div id="box">
<button>开关</button>
</div>
<script>
var box=document.querySelector('#box');
var btn=document.querySelector('button');
var flag=0;
btn.onclick=function(){
if(flag==0){
box.style.backgroundColor='#fff';
flag=1;
}else{
box.style.backgroundColor='black';
flag=0;
}
}
</script>
</body>
</html>
DOM重点核心
主要是针对元素的操作
1.创建元素
document.write; innerHTML; createElement
2.增加元素
appendChild; insertBefore
3.删除元素
removeChild
4.修改元素
修改元素属性:src; href; title等
修改普通元素内容:innerHTML; innerText
修改表单元素:value; type; disabled等
修改元素样式:style; className
5.查询元素
DOM提供的API方法: getElementById; getElementByTagName
H5提供的新方法:querySelector; querySelectorAll
利用节点操作获取元素:parentNode; children; previousElementSibling; nextElementSibling
6.属性操作
主要针对自定义属性
设置dom属性值:setAttribute
得到dom属性值:getAttribute
移除属性: removeAttribute
7.事件操作
事件源.事件类型=事件处理程序
鼠标事件:
onclick; onmouseover; onmouseout; onfocus; onblur; onmouseup; onmousedown;