JsDOM
什么是DOM
Document Object Model 文档对象模型
在JS中,所有的事物都是节点,元素、文本等都是节点。把浏览器中的标签看成树状结构,每个标签看成一个节点(dom元素)。
面向对象:三个特性 “封装、继承、多态”
一个对象应该有:属性、方法
万事万物皆对象,在js中如果没有对象,new一个
DOM是树形结构,有继承概念,管理document下的所有标签
在DOM树中,一切皆是节点
元素、节点表示的就是标签对象
应用场景:可以通过节点进行DOM对象的增删改查
DOM可以做什么?
比如能让div颜色切换 以开灯举例: 1.先找到开关 (先找到事件对象——事件源) 2.摁一下 (事件) 3.灯亮了 (业务逻辑 事件驱动) DOM执行流程 1.找到对象(元素节点) (获取DOM) 2.设置标签的属性 (对于标签属性的操作) 3.设置元素的样式 (对于样式属性的操作) 4.设置标签值的操作 5.动态的创建元素和删除元素 (对于DOM的建增删改) 6.事件的触发响应(找到事件源——事件内容——事件驱动程序) (js事件,ECMAScript相关知识点对DOM进行操作)
获取DOM节点的方法
//通过id获取,唯一的 var oDiv = document.getElementById('box'); //通过类名获取 var oDiv = document.getElementsByClassName('.box')[0]; //通过标签名获取 var oDiv = document.getElementsByTagName('div')[0];
常用的DOM节点
DOM的标签结构获取
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title></title> <link rel="stylesheet" href=""> </head> <body> <div id="box" class="box"></div> <div id="box1" class="box"></div> <div id="box2" class="box"></div> <script type="text/javascript"> // 1.获取文档对象(事件源的获取) console.log(document); // 2.获取html console.log(document.documentElement); console.dir(document.documentElement); // 3.获取body console.log(document.body); // 4.获取body中元素节点对象的三种方式 // 4.1 通过ID获取 var oDiv = document.getElementById('box'); console.log(oDiv); // 4.2 通过类名获取 var oDivs = document.getElementsByClassName('box'); console.log(oDivs); // 4.3 通过标签名获取 var oDiv1 = document.getElementsByTagName('div'); console.log(oDiv1); // HTMLCollection(3) [div#box.box, div#box1.box, div#box2.box, box: div#box.box, box1: div#box1.box, box2: div#box2.box] // 获取到的值是一个伪数组,不能使用数组的方法 var oDiv2 = document.getElementsByClassName('box')[0]; var oDiv3 = document.getElementsByTagName('div')[1]; console.log(oDiv2); console.log(oDiv3); </script> </body> </html>
绑定事件的方式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> #box{ width: 100px; height: 100px; background-color: red; } </style> <!--<script type="text/javascript">--> <!--onload事件 js中通常有一个入口函数,在js中使用window.onload()方法 问题:1.等待着文档和图片资源加载完毕后,才会触发onload事件 2.window.onload有事件覆盖现象,如果写两个onload方法,后面的会覆盖前面的,只会显示后面的 window.onload=匿名函数() window.onload = function(){ var oDiv = document.getElementById('box'); console.log(oDiv); } --> <!--</script>--> </head> <body> <div id="box"></div> <!--尽量写在body之后,这样就省去了windows.onload方法 --> <script type="text/javascript"> // 1.获取事件源 window.onload = function() { var oDiv = document.getElementById('box'); console.log(oDiv); // 2.事件 方式一:直接绑定匿名函数 oDiv.onclick = function () { // 3.事件驱动 alert(1); } // 方式二:先单独定义函数,再绑定 // fn()获取的是函数返回值,fn获取的是函数本身 /*oDiv.onclick = fn; //这里一定没有括号 //从这里一绑定,函数就执行了,这种方式不用记了 console.log(fn()); //这里打印的是函数返回值 console.log(fn); //这里打印的是函数本身 function fn() { alert(1); return(1); } */ } </script> </body> </html>
标签的样式属性操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> .box{ width: 100px; height: 100px; /*background-color: red;*/ /*这样写是内接式*/ } </style> </head> <body> <!--需求:有一个盒子,初始化的时候是红色的,点击盒子以后切换成绿色--> <!--<div class="box"></div>--> <div class="box" style="background-color: red"></div> <!--这样写,style是行内样式,就能获取到声明的样式了--> <script type="text/javascript"> //不这样写,在内接式方法里声明,会用行内样式直接覆 // 1.获取事件源 盖内接样式,不会获取到一开始声明的样式了 var oDiv = document.getElementsByClassName('box')[0]; // 2.事件 oDiv.onclick = function () { // 3.事件驱动 console.log(oDiv.style); // 点语法:get和set // 获取值:get方法 获取的是行内样式,与内接和外接没有任何关系 console.log(oDiv.style.backgroundColor); // 设置值:set方法 // 在style中书写的方法,比如bgc,通过js设置的时候,要写成驼峰 oDiv.style.backgroundColor = 'green'; oDiv.style.width = '200px'; oDiv.style.marginLeft = '10px'; } </script> </body> </html>
标签值的操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> </style> </head> <body> <input type="text" name="user" value="123" id="oinput"> <button id="btn">设置值</button> <div id="box"> egon <h3>哈哈哈</h3> </div> <script type="text/javascript"> window.onload = function () { /* var oBtn = document.getElementById('btn'); var oDiv = document.getElementById('box'); var oInput = document.getElementById('oinput'); */ // oBtn.onclick = function () { // // innerText只获取文本 // console.log(oDiv.innerText); // // innerHtml获取所有的子节点内容,包含文本、标签、空格、换行 // console.log(oDiv.innerHTML); // // console.log(oDiv.innerHTML.trim()); //去空格 // oDiv.innerText = 'alex'; // oDiv.innerHTML = 'alex<h2>SB</h2>'; // // 表单控件中有value属性的,必须通过value来设置值和赋值 // oInput.value = '234'; // // // } // 上面这些改写成函数 function $(id){ return document.getElementById(id); } $('btn').onclick = function () { // innerText只获取文本 console.log($('box').innerText); // innerHtml获取所有的子节点内容,包含文本、标签、空格、换行 console.log($('box').innerHTML); // console.log(oDiv.innerHTML.trim()); //去空格 $('box').innerText = 'alex'; $('box').innerHTML = 'alex<h2>SB</h2>'; // 表单控件中有value属性的,必须通过value来设置值和赋值 $('oinput').value = '234'; } } </script> </body> </html>
标签属性的操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/css"> a{ display: inline-block; } </script> </head> <body> <!--能操作标签中的id、class、title、image中的src属性 a中的href属性等肉眼能见的属性--> <a href="javascript:void (0)"> <img src="./images/image1.png" alt="上一张" id="prev"> </a> <script type="text/javascript"> window.onload = function () { // 1.获取事件源 var oImage = document.getElementById('prev'); // 2.事件 oImage.onmouseover = function () { // console.log(oImage); // this等于python中的self,谁调用self就指的谁 // console.log(this); console.log(this.getAttribute('src')); // = console.log(this.src); console.log(this.src); // 这种方法获取的是绝对路径 console.log(this.getAttribute('id')); // = console.log(this.id); console.log(this.getAttribute('alt')); // 属性的设置 // this.setAttribute(key,value) this.setAttribute('src', './images/image2.png'); }; oImage.onmouseout = function () { // this.setAttribute('src', './images/image1.png'); this.src = './images/image1.png'; }; } </script> </body> </html>
让元素显示隐藏的几种情况1通过控制样式属性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> #box{ width: 200px; height: 200px; background-color: red; } </style> </head> <body> <button id="btn">隐藏</button> <div id="box"></div> <script type="text/javascript"> window.onload =function () { function $(id) { return document.getElementById(id); } // 1.通过控制样式属性的display属性来对盒子进行控制 var isShow = true; $('btn').onclick = function () { if(isShow){ $('box').style.display = 'none'; isShow = false; this.innerText = '显示'; }else{ $('box').style.display = 'block'; isShow = true; this.innerText = '隐藏'; } } } </script> </body> </html>
让元素显示隐藏的几种情况2通过控制类
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--通过这种方式进行切换,初始化的时候会有渲染开销,网页中频繁切换的情况时,推荐使用这种方法--> <style type="text/css"> #box{ width: 200px; height: 200px; background-color: red; } .active{ display: none; } </style> </head> <body> <button id="btn">隐藏</button> <div id="box" class="box"></div> <script type="text/javascript"> window.onload = function () { function $(id) { return document.getElementById(id); } var isShow = true; $('btn').onclick = function () { // 在js中设置类,需要通过className = 'active' if(isShow){ $('box').className += ' active'; this.innerText = '显示'; isShow = false; }else{ $('box').className = 'box'; this.innerText = '隐藏'; isShow = true } } } </script> </body> </html>
DOM的节点操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> </style> </head> <body> <button id="create">创建</button> <button id="remove">移除</button> <div id="box"> <h3 id="haha">哈哈</h3> <!--<p>alex</p>--> <!--这种方式对页面性能是有损耗的,如果页面中出现频繁性的切换,不推荐使用这种方法--> <!--这种方法常用在登陆、注册框等一次性变更的页面上--> </div> <script type="text/javascript"> window.onload = function () { function $(id) { return document.getElementById(id); } var oP = null; $('create').onclick = function () { // 创建P标签元素 oP = document.createElement('h2'); // 设置内容 oP.innerText = 'alex'; // 追加元素 父子之间追加 父元素.appendChild(子元素) $('box').appendChild(oP); // 父.insertBefore(新的子节点,作为参考的节点) $('box').insertBefore(oP,$('haha')); }; $('remove').onclick = function () { // 移除元素 父元素.removechild(子元素) } } </script> </body> </html>
DOM节点操作的补充
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> </style> </head> <body> <div id="box"> <button id="btn">创建 <span>哈哈 <span> 嘿嘿 </span> </span> <span>哈哈</span> </button> </div> <script type="text/javascript"> window.onload = function () { function $(id) { return document.getElementById(id); }; // 获取父节点的方法 $('btn').parentNode; console.log($('btn').parentNode); // 获取子节点的方法 结果是复数 $('btn').children; console.log($('btn').children); // 自己删除自己 $('btn').onclick = function () { this.parentNode.removeChild(this); } } </script> </body> </html>
模态框案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>模态框</title> <style type="text/css"> *{ padding: 0; margin: 0; } html body{ width: 100%; height: 100%; } #bg{ position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: #666; } #login{ width: 300px; height: 300px; margin: 0 auto; border-radius: 3px; line-height: 300px; text-align: center; background-color: #fff; position: relative; } #close{ position: absolute; right: 0; top: 0; width: 10px; height: 10px; line-height: 10px; text-align: center; color: #fff; cursor: pointer; background-color: blue; } </style> </head> <body> <!--需求:打开网页时,打开一个背景图,在中心弹出一个登陆框,登陆框右上角有关闭按钮--> <button id="btn">登陆</button> <script type="text/javascript"> function $(id) { return document.getElementById(id); } // 1.点击登陆按钮,弹出登陆框 // 创建背景 var oBg = document.createElement('div'); // 创建登陆框 var oLogin = document.createElement('p'); // 关闭按钮 var oClose = document.createElement('span'); oBg.id = 'bg'; oLogin.id = 'login'; oClose.id = 'close'; oClose.innerText = 'X'; oLogin.innerHTML = '登陆框成功弹出'; // 追加元素 oBg.appendChild(oLogin); oLogin.appendChild(oClose); $('btn').onclick = function(){ // 创建背景图 this.parentNode.appendChild(oBg); // this.parentNode.removeChild(this); $('btn').style.display = 'none'; } // 追加元素 oBg.appendChild(oLogin); oLogin.appendChild(oClose); oClose.onclick = function () { oBg.parentNode.removeChild(oBg); $('btn').style.display = 'block'; } </script> </body> </html>
hover选择器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> button{ width: 100px; height: 30px; margin: 20px; cursor: pointer; } button.active{ background-color: green; } </style> </head> <body> <!--需求:鼠标悬浮哪个button上,哪个button就变成绿色背景--> <button>按钮1</button> <button>按钮2</button> <button>按钮3</button> <button>按钮4</button> <button>按钮5</button> <script type="text/javascript"> var oBtns = document.getElementsByTagName('button'); for(var i = 0; i < oBtns.length; i++){ oBtns[i].onmouseover = function () { for(var j = 0; j < oBtns.length; j++){ oBtns[j].className = ''; } this.className = 'active'; } } for(var i = 0; i < oBtns.length; i++){ oBtns[i].onmouseleave = function () { this.className = ''; } } </script> </body> </html>
tab栏选项卡
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> *{ padding: 0; margin: 0; } ul li{ list-style: none; } #tab{ width: 480px; margin: 0 auto; border: 1px solid red; } ul{ width: 100%; overflow: hidden; } #tab ul li{ float: left; width: 160px; height: 60px; line-height: 60px; text-align: center; background-color: #eee; } #tab ul li a{ color: #000; display: block; width: 100%; height: 100%; text-decoration: none; } #tab ul li.active{ background-color: red; } #tab p{ display: none; height: 200px; text-align: center; line-height: 200px; background-color: red; } #tab p.active{ display: block; } </style> </head> <body> <div id="tab"> <ul> <li class="active"> <a href="javascript:void(0)">首页</a> </li> <li> <a href="javascript:void(0)">新闻</a> </li> <li> <a href="javascript:void(0)">图片</a> </li> </ul> <p class="active">首页内容</p> <p>新闻内容</p> <p>图片内容</p> </div> <!--需求:鼠标放在上面的li上,li本身变色(添加类),对应下面的P标签也要显示出来(添加类)--> <!--思路:1.点亮上面的盒子 2.利用索引值来显示下面的P标签--> <script type="text/javascript"> var tabLi = document.getElementsByTagName('li'); var tabP = document.getElementsByTagName('p'); for(var i = 0;i < tabLi.length; i++){ tabLi[i].index = i; tabLi[i].onmouseover = function () { for(var j = 0; j < tabLi.length; j++){ tabLi[j].className = ''; tabP[j].className = ''; } this.className = 'active'; tabP[this.index].className = 'active'; } } for(var i = 0; i < tabLi.length; i++){ tabLi[i].onmouseout = function () { this.className = ''; tabP[this.index].className = ''; } } </script> </body> </html>
es6的语法解决tab栏选项卡
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> *{ padding: 0; margin: 0; } ul li{ list-style: none; } #tab{ width: 480px; margin: 0 auto; border: 1px solid red; } #tab ul li{ width: 160px; height: 60px; float: left; line-height: 60px; text-align: center; background-color: #ccc; } #tab ul li a{ width: 100%; height: 100%; color: #fff; display: block; text-decoration: none; } #tab ul li.active{ background-color: red; } #tab p{ display: none; height: 300px; line-height: 300px; text-align: center; background-color: red; color: #fff; } #tab p.active{ display: block; } </style> </head> <body> <div id="tab"> <ul> <li class="active"> <a href="javascript:void(0)">首页</a> </li> <li> <a href="javascript:void(0)">新闻</a> </li> <li> <a href="javascript:void(0)">图片</a> </li> </ul> <p class="active">首页内容</p> <p>新闻内容</p> <p>图片内容</p> </div> <script> /* 变量提升 var a; console.log(a) //undefined a = 10; console.log(a) //10 */ /* 在es6中,使用let来声明块级作用域来解决这个问题 { let a = 10; console.log(a); //10 } console.log(a); //a is not defined */ var tabLi = document.getElementsByTagName('li'); var tabP = document.getElementsByTagName('p'); for(let i = 0; i < tabLi.length; i ++){ tabLi[i].onmouseover = function(){ for(var j = 0; j < tabLi.length; j ++){ tabLi[j].className = ''; tabP[j].className = ''; } this.className = 'active'; tabP[i].className = 'active'; } } </script> </body> </html>
client系列
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> .box{ width: 200px; height: 200px; position: absolute; border: 1px solid red; padding: 80px; } </style> </head> <body> <div class="box">clientTop 内容区域到边框顶部的距离 ,说白了,就是边框的高度<br> clientLeft 内容区域到边框左部的距离,说白了就是边框的乱度<br> clientWidth 内容区域+左右padding 可视宽度<br> clientHeight 内容区域+ 上下padding 可视高度 </div> <script type="text/javascript"> var oBox = document.getElementsByClassName('box')[0]; console.log(oBox.clientTop); console.log(oBox.clientLeft); console.log(oBox.clientHeight); console.log(oBox.clientWidth); </script> </body> </html>
屏幕的可视宽高
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> </style> </head> <body> <script type="text/javascript"> // document.documentElement获取的是html标签值 window.onload = function () { // console.log(document.documentElement.clientWidth); // console.log(document.documentElement.clientHeight); window.onresize = function () { console.log(document.documentElement.clientWidth); console.log(document.documentElement.clientHeight); } // 窗口大小发生变化时,会触发下面方法 } </script> </body> </html>
offset偏移量
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> *{ padding: 0; margin: 0; } </style> </head> <body style="height: 2000px"> <div> <div class="wrap" style=" width: 300px;height: 300px;background-color: green"> <div id="box" style="width: 200px;height: 200px;border: 5px solid red;position: absolute;top:50px;left: 30px;"> </div> </div> </div> </body> <script type="text/javascript"> window.onload = function(){ var box = document.getElementById('box'); /* offsetWidth占位宽 内容+padding+border offsetHeight占位高 offsetTop: 如果盒子没有设置定位 到body的顶部的距离,如果盒子设置定位,那么是以父辈为基准的top值 offsetLeft: 如果盒子没有设置定位 到body的左部的距离,如果盒子设置定位,那么是以父辈为基准的left值 * */ console.log(box.offsetTop); console.log(box.offsetLeft); console.log(box.offsetWidth); console.log(box.offsetHeight); } </script> </html>
scroll滚动系列
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> *{padding: 0;margin: 0;} </style> </head> <body style="width: 2000px;height: 2000px;"> <div style="height: 200px;background-color: red;"></div> <div style="height: 200px;background-color: green;"></div> <div style="height: 200px;background-color: yellow;"></div> <div style="height: 200px;background-color: blue;"></div> <div style="height: 200px;background-color: gray;"></div> <div id = 'scroll' style="width: 200px;height: 200px;border: 1px solid red;overflow: auto;padding: 10px;margin: 5px 0px 0px 0px;"> <p>学习新技能,达成人生目标,开始用自己的力量影响世界学习新技能,达成人生目标,开始用自己的力量影响世界学习新技能,达成人生目标,开始用自己的力量影响世界学习新技能,达成人生目标,开始用自己的力量影响世界学习新技能,达成人生目标,开始用自己的力量影响世界学习新技能,达成人生目标,开始用自己的力量影响世界学习新技能,达成人生目标,开始用自己的力量影响世界学习新技能,达成人生目标,开始用自己的力量影响世界学习新技能,达成人生目标,开始用自己的力量影响世界学习新技能,达成人生目标,开始用自己的力量影响世界学习新技能,达成人生目标,开始用自己的力量影响世界学习新技能,达成人生目标,开始用自己的力量影响世界 </p> </div> </body> <script type="text/javascript"> window.onload = function(){ //实施监听滚动事件 window.onscroll = function(){ // console.log(1111) console.log('上'+document.documentElement.scrollTop); // console.log('左'+document.documentElement.scrollLeft); // console.log('宽'+document.documentElement.scrollWidth); // console.log('高'+document.documentElement.scrollHeight); } var s = document.getElementById('scroll'); s.onscroll = function(){ // scrollHeight : 内容的高度+padding 不包含边框 console.log('上'+s.scrollTop); console.log('左'+s.scrollLeft); console.log('宽'+s.scrollWidth); console.log('高'+s.scrollHeight); } } </script> </html>
定时器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style type="text/css"> #box{ width: 100px; height: 20px; background-color: greenyellow; line-height: 20px; text-align: center; } </style> </head> <body> <div id="box"><h3>123</h3></div> <button id="clear">清除</button> <button id="animate">播放动画</button> <script type="text/javascript"> console.log('开始'); // 一次性定时器 // 2秒之后运行回调函数,222如果先于回调函数调用,证明setTimeout可以做异步操作 // 未来如果对数据操作出现数据堵塞问题,可以使用setTimeout来执行异步操作 setTimeout(function () { console.log('走到尽头了'); },100); console.log('222'); var num = 0; var oDiv = document.getElementById('box'); var oAnimate = document.getElementById('animate'); console.log('又开始了'); let timer; oAnimate.onclick = function () { // 用定时器的时候,要先清定时器,再开定时器 clearInterval(timer); timer = setInterval(function () { num++; console.log(num); oDiv.style.marginLeft= num*5 + 'px'; }, 1000); } // 清除定时器 // clearTimeout(); // clearInterval(); var oClear = document.getElementById('clear'); oClear.onclick = function () { clearInterval(timer); } </script> </body> </html>