目录
一. 简介
二.获取元素
三.事件
四.操作元素
1.操作元素内容
2.操作元素属性
五.节点
1.为什么学节点操作?
2.节点的介绍
3.节点的操作
六.案例
1.分时问候
2.仿京东显示隐藏密码明文
3.仿淘宝关闭二维码
栏切换 223
一. 简介
文档对象模型(Document Object Model)是处理可扩展标记语言(HTML,XML)的标准变成接口。
DOM树
文档对象模型指的就是将这个文档中的内容都看成对象。
二.获取元素
根据ID获取
-
<body>
-
<div id="time">2022-4-11</div>
-
<script>
-
//因为文档页面从上往下加载,先得有标签,所以script写到标签的下面
-
var timer = document.getElementById('time');
-
alert(typeof timer); //object
-
console.log(timer);
-
console.dir(timer);
-
</script>
-
</body>
根据标签名获取
<body> <div id="time" class="ti">2022-4-11</div> <div>2022-4-12</div> <script> var timer = document.getElementsByTagName('div'); console.log(timer); //object //返回的是伪数组,不支持push pop操作 </script> </body>document是获取页面上所有的
如何单独获取某个父标签下的子标签
<body> <ol id="l1"> <li></li> <li></li> <li></li> </ol> <script> var elements = document.getElementsByTagName('ol'); var lis = elements[0].getElementsByTagName('li'); console.log(lis); var l = document.getElementById('l1'); var liss = l.getElementsByTagName('li'); console.log(liss); </script> </body>
根据类名获取元素
var l = document.getElementsByClassName('box1');
指定选择器获取元素
querySelector
指定选择器,可以是标签,类名或id。只返回符合条件的第一个元素
<box class="box1" id="box11">a</box> var boxs = document.querySelector('#box11'); var boxs = document.querySelector('.box1');querySelectorAll
指定选择器,可以获取所有符合条件的元素
var boxs = document.querySelectorAll('.box1');
特殊元素获取
获取body和html
//获取body var b = document.body; console.log(b); //获取html var h = document.documentElement; console.log(h);
三.事件
事件基础
事件由三部分组成:事件源,事件类型,事件处理程序
事件源:触发的对象,比如按钮
事件类型:如何触发,比如鼠标点击,鼠标经过等
事件处理程序:通过函数赋值的方式完成
<body> <button id="btn">A</button> <script> var btn = document.getElementById('btn'); btn.onclick = function () { alert("B"); } </script> </body>
给多个事件源绑定事件
<body> <button>A</button> <button>B</button> <button>C</button> <button>D</button> <button>E</button> <script> var btns = document.getElementsByTagName('button'); for(var i = 0; i < btns.length; i++){ btns[i].onclick = function (){ //其他的按钮颜色失去 for(var i = 0; i < btns.length; i++){ btns[i].style.color = ''; } //当前按钮颜色变色 this.style.color = 'red'; } } </script> </body>排他思想:首先先排除其他人,再设置自己的样式2
注册事件(绑定事件)
传统注册方式
利用on开头的,如onclick
= function(){} 这种方式一个元素同一个事件只能设置一个处理函数,后面的会覆盖掉前面的,因为这种方式是赋值方式
方法监听注册
同一个事件可以添加多个监听器
<body> <button>tap me</button> <script> var btn = document.querySelector('button'); btn.addEventListener('click',function(){ alert('oops'); }) /* * 第一个参数 type 事件类型字符串 如click,mouseover * 第二个参数 listener 事件处理函数,当事件发生时,会调用改监听函数 * 第三个参数 useCapture 可选参数,是一个布尔值,默认是false * */ </script> </body>
删除事件(解绑事件)
传统注册方式
= null 赋值为null即可
方法监听注册
<body> <button>tap me</button> <script> var btn = document.querySelector('button'); btn.addEventListener('click',fn); function fn(){ alert('oops'); btn.removeEventListener('click',fn); } </script>传入函数的时候需要传入有名字的函数,这样后面才能解绑。
DOM事件流
事件流描述的是从页面中接收事件的顺序。
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。
给div注册事件,它的父节点们都会收到注册事件。
代码演示DOM流
演示1
点击son事件的顺序:son
<body> <div class="father"> <div class="son"></div> </div> <script> var son = document.querySelector('.son'); //JS代码只能执行捕获或冒泡其中的一个阶段 //onclick只能得到冒泡阶段 //捕获阶段如果addEventListener第三个参数如果是true,则处于捕获阶段 son.addEventListener('click',function (){ alert('son'); },true); //虽然给son添加了点击事件,但是document先得到点击,但是document没有函数,所以会没有执行效果 </script> </body>演示2
点击son事件出现的顺序:father-son
<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .son{ width: 100px; height: 100px; background-color: green; } .father{ width: 200px; height: 200px; background-color: salmon; } </style> </head> <body> <div class="father"> <div class="son"></div> </div> <script> var son = document.querySelector('.son'); //JS代码只能执行捕获或冒泡其中的一个阶段 //onclick只能得到冒泡阶段 //捕获阶段如果addEventListener第三个参数如果是true,则处于捕获阶段 son.addEventListener('click',function (){ alert('son'); },true); var father = document.querySelector('.father'); father.addEventListener('click',function (){ alert('father'); },true); //虽然给son添加了点击事件,但是document先得到点击,这里给father设置了点击事件,那么点击son,father先弹出 </script> </body> </html>如果添加事件的方法中的true改为false或不写,那么就事件流就处于冒泡阶段,先从son开始。
事件对象
var son = document.querySelector('.son'); son.onclick = function (event){ //event是一个事件对象,当作形参来看,有了事件后,事件对象才存在,由系统自动创建,不需要我们传递参数 //事件对象是我们事件的一系列相关数据的集合,跟事件相关的比如鼠标点击里面包含了鼠标的相关信息,鼠标坐标等 console.log(event); }
var son = document.querySelector('.son'); son.addEventListener('click',function (event){ console.log(event);})事件对象常见方法
和this区别
:比如点击div触发了事件,那么就返回事件源的div
this:比如在ul中有很多li,给ul绑定事件,点击了li的话,this会返回ul而不是li,会返回li,因为this指向了被绑定的元素对象。
阻止默认行为
如让链接不跳转,让提交按钮不提交。
var a = document.querySelector('a'); a.addEventListener('click',function (e){ e.preventDefault(); }); return false 也能阻止
阻止事件冒泡
var a = document.querySelector('a'); a.addEventListener('click',function (e){ e.preventDefault(); e.stopPropagation(); })在最下面一层设置阻止冒泡,就会停止向上冒泡了
= true 也可以
事件委托
事件冒泡可以应用的地方
事件委托的原理:不是给每个子节点单独设置事件监听器,而是事件监听器设置在父节点上,然后利用冒泡原理影响设置每个子节点。
<body> <ul> <li>A</li> <li>B</li> <li>C</li> <li>D</li> <li>E</li> </ul> <script> var ul = document.querySelector('ul'); ul.addEventListener('click',function (e){ alert('ABCDE'); e.target.style.backgroundColor = 'pink';//点谁谁变色 }) </script> </body>
常见鼠标事件
禁止鼠标右键菜单
contextmenu主要控制应该何时显示上下文菜单,主要用于取消默认上下文菜单
选中p中的文字无法右键
<body> <p>我是一个PP</p> <script> var pp = document.querySelector('p'); pp.addEventListener('contextmenu',function (e){ e.preventDefault(); }) </script> </body>禁止鼠标选中
<body> <p>我是一个PP</p> <script> var pp = document.querySelector('p'); pp.addEventListener('selectstart',function (e){ e.preventDefault(); }) </script> </body>鼠标事件对象
常见键盘事件
keypress区别大小写,keyup和keydown不区分大小写
键盘事件对象
四.操作元素
1.操作元素内容
操作元素的内容 innerText 或 innerHTML
<button id="btn">A</button> var btn = document.getElementById('btn'); btn.onclick = function (){ btn.innerText = 'B'; }点击按钮,将A改成B
两者的区别
不识别HTML标签,innerHTML标签识别HTML标签
var btn = document.getElementById('btn'); btn.innerText = '<strong>C</strong>';//<strong>C</strong> btn.innerHTML = '<strong>C</strong>';//C2.还可以获取内容,innerText 不识别标签,innerHTML识别标签,并且保留空格和换行。
<p> 我是p <span> 我是span </span> </p> var btn = document.getElementById('btn'); console.log(btn.innerText);
<p> 我是p <span> 我是span </span> </p> var btn = document.getElementsByTagName('p'); console.log(btn[0].innerHTML);
2.操作元素属性
操作元素的属性
<body> <p style="font-size:50px"> 我是p <span> 我是span </span> </p> <script> var btn = document.getElementsByTagName('p'); btn[0].style = "font-size:500px"; </script> </body>在通过获取的元素修改样式时,比如修改color,修改后的样式等于行内样式,所以会覆盖之前的样式
操作属性style的其他属性
<body> <p>我是P</p> <script> var p = document.querySelector('p'); p.style.color = 'red'; </script> </body>当要修改的属性多了起来,通过这种方式就会比较麻烦
<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .change{ color:green; } </style> </head> <body> <p>我是P</p> <script> var p = document.querySelector('p'); p.className = 'change'; </script> </body> </html>使用这种方式,先设置样式,再给标签更改类属性
<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .change{ color:green; } .first{ font-size: 50px; } </style> </head> <body> <p class="first">我是P</p> <script> var p = document.querySelector('p'); p.className = p.className+' change'; </script> </body> </html>这样还可以保留以前的类的样式,也就是一个标签设置了多个类。
获取属性的属性值
<body> <button class="bnt1" id="btn1">A</button> <button>B</button> <button>C</button> <button>D</button> <button>E</button> <script> var btn = document.querySelector('.bnt1'); //方式1 element.属性 alert(btn.id); alert(btn.className); //方式2 ('属性'); alert(btn.getAttribute('class')); </script> </body>两种方式的用法区别:
第一种方式只能获得内置的属性。
第二种方式还能获得自定义的属性。
这种属性是为了做区别用的,比如下面
<p index="1"></p>
设置属性值
<body> <button class="btn1" id="btn1" index="1">A</button> <script> var btn = document.querySelector('.bnt1'); //方式1 element.属性 btn.className = 'btn'; //方式2 ('属性','值'); btn.setAttribute('index','0'); </script> </body>设置内置属性和自定义属性的两种方法
移除属性
btn.removeAttribute('index');
自定义属性
为了防止自定义属性和内置属性引发歧义,规定自定义属性用data-开头为属性名。
自定义属性是为了保存一些数据或者使页面某些标签做一些区分。
获取自定义属性值 getAttribute
设置或添加自定义属性值 setAttribute
移除自定义属性 removeAttribute
五.节点
1.为什么学节点操作?
利用DOM提供的方法获取元素时,用的是()等等。
逻辑性不强,且繁琐。
利用节点可以根据层级关系获取元素
节点的范围包括元素,元素只是标签,节点除了标签还可以是属性,属性的值,标签的内容等。
DOM树种所有节点都可以被访问。
2.节点的介绍
节点包括节点类型(nodeType),节点名称(nodeName),节点值(nodeValue)。
节点类型
元素节点nodeType为1
属性节点nodeType为2
文本节点nodeType为3(包含文字,空格,换行)
节点层级
父子兄层级关系
父级节点
var bb = btn.parentNode;//得到最近的父亲节点
子节点
var pp = btn.childNodes;//得到所有子节点,子节点包括元素节点,文本节点,空格等
var pp = btn.children;//得到所有子节点,只包括元素节点 var pp0 = btn.children[0];//得到第一个子节点
var pp = btn.firstChild;//得到第一个子节点,不管是文本节点还是元素节点 var ppp = btn.lastChild;//得到最后一个子节点,不管是文本节点还是元素节点 var pp0 = btn.firstElementChild;//返回第一个元素节点 var ppp0 = btn.lastElementChild;//返回最后一个元素节点兄弟节点
var next = btn.nextSibling;//下一个兄弟节点,不管是元素节点还是文本节点 var previous = btn.previousSibling;//上一个兄弟节点,不管是元素节点还是文本节点 var btn2 = btn.nextElementSibling;//下一个兄弟元素节点 var btn0 = btn.previousElementSibling; //上一个兄弟元素节点
3.节点的操作
创建节点
比如添加评论的功能,添加了一个p,相当于添加了节点
只创建节点是没有效果的,还需要添加节点
添加节点
<body> <ul id="u1"> <li id="l1"></li> </ul> <script> //创建元素 var li = document.createElement('li'); //添加元素 var ul = document.querySelector('#ul'); ul.appendChild(li);//ul是父节点,li是子节点,将子节点放入到父节点种,追加的形式放入到父节点种 ul.insertBefore(li,ul.children[0]);//在ul第一个子节点前面插入li </script> </body>删除节点
<body> <ul id="u1"> <li id="l1">A</li> <li>B</li> <li>C</li> </ul> <script> var ul = document.querySelector('ul'); ul.removeChild(ul.children[0]); </script> </body>复制节点
<body> <ul id="u1"> <li id="l1">A</li> <li>B</li> <li>C</li> </ul> <script> var ul = document.querySelector('ul'); var clone = ul.children[0].cloneNode();//如果括号的参数为空或false,就是浅拷贝,只克隆复制节点本身,不克隆里面的节点 ul.appendChild(clone); var clone2 = ul.children[1].cloneNode(true);//克隆节点和节点的内容 ul.appendChild(clone2); </script> </body>
六.案例
1.分时问候
根据时间不同,页面显示不同图片,显示不同问候语。
<body> <img src="#" alt=""> <div>上午好</div> <script> //1.获取元素 var img = document.querySelector('img'); var div = document.querySelector('div'); //2.获取当前时间 var date = new Date(); var h = date.getHours(); //3.判断 if(h < 12 ){ div.innerText = "上午好"; }else if(h < 13){ div.innerText = '中午好'; }else if(h < 19){ div.innerText = '下午好'; }else { div.innerText = '晚上好'; } </script> </body>所用知识:
1.获取元素
2.获取时间,通过小时判断时段
3.修改元素内容,通过innerText修改标签内的内容
2.仿京东显示隐藏密码明文
注册账号时,密码输入栏中右侧按钮,单击显示密码,再点击显示*。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script> </script> <style> .box{ width: 400px; border-bottom: 1px solid #ccc; margin: 100px auto; } .box input{ width: 370px; height: 30px; border: 10px;/*去掉未选中时显示的框*/ outline: none;/*去掉选中后显示的框框*/ } </style> </head> <body> <div class="box"> <input type="password" id="pwd"> <label for="pwd"> <img src="../images/" alt="" width="18px" height="8px" id="eye"> </label> </div> <script> //获取元素 var img = document.querySelector('#eye'); var pwd = document.querySelector('#pwd'); var flag = 0; img.onclick = function (){ if(flag == 0){ flag = 1; img.src = "../images/"; pwd.type = 'text'; }else{ flag = 0; img.src = "../images/"; pwd.type = 'password'; } } </script> </body> </html>所用知识:
1.获取元素
2.修改元素属性,通过修改input标签中的password和text属性来实现密码显示与隐藏。
3.仿淘宝关闭二维码
<body> <div class="box"> <img src="../images/" alt="" width="71px" height="68px"> <i id="del">×</i> </div> <script> //获取元素 var img = document.querySelector('img'); var del = document.querySelector('#del'); del.onclick = function (){ // = true; img.style.display = 'none'; } </script> </body>两种隐藏方法都可以
点击×,图片隐藏起来
4.循环精灵图 211
5.显示隐藏文本框的内容 212
6.密码框格式提示错误信息 214
7.百度换肤 217
8.表格隔行变色 218
9.表单全选取消 219+220
栏切换 223
11.新浪下拉菜单
碰到链接显示菜单
-
<html lang="en">
-
<head>
-
<meta charset="UTF-8">
-
<title>Title</title>
-
<script src="jquery-3.4."></script>
-
<script>
-
$(function () {
-
var nav = document.querySelector('.nav');
-
var lis = nav.children;//得到四个li
-
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>
-
<style>
-
a{
-
text-decoration: none;
-
color:black;
-
}
-
.nav ul{
-
display: none;
-
width: 100%;
-
}
-
.nav>li{
-
float: left;
-
margin: 10px;
-
}
-
-
</style>
-
</head>
-
<body>
-
<ul class="nav">
-
<li>
-
<a href="#">微博</a>
-
<ul>
-
<li>私信</li>
-
<li>评论</li>
-
<li>@我</li>
-
</ul>
-
</li>
-
<li>
-
<a href="#">微博</a>
-
<ul>
-
<li>私信</li>
-
<li>评论</li>
-
<li>@我</li>
-
</ul>
-
</li>
-
<li>
-
<a href="#">微博</a>
-
<ul>
-
<li>私信</li>
-
<li>评论</li>
-
<li>@我</li>
-
</ul>
-
</li>
-
<li>
-
<a href="#">微博</a>
-
<ul>
-
<li>私信</li>
-
<li>评论</li>
-
<li>@我</li>
-
</ul>
-
</li>
-
</ul>
-
</body>
-
</html>
12.发布留言 234
13.删除留言 236
14.动态生成表格 238
15.跟随鼠标的天使 267
16.模拟京东输入内容案例