JavaScript(2)-DOM

时间:2024-11-18 16:34:45

目录

一. 简介

二.获取元素

三.事件

四.操作元素

1.操作元素内容 

2.操作元素属性 

 五.节点

1.为什么学节点操作?

2.节点的介绍

3.节点的操作

六.案例

1.分时问候

2.仿京东显示隐藏密码明文

3.仿淘宝关闭二维码

栏切换 223



一. 简介

文档对象模型(Document Object Model)是处理可扩展标记语言(HTML,XML)的标准变成接口。

DOM树

文档对象模型指的就是将这个文档中的内容都看成对象。

二.获取元素

根据ID获取

  1. <body>
  2. <div id="time">2022-4-11</div>
  3. <script>
  4. //因为文档页面从上往下加载,先得有标签,所以script写到标签的下面
  5. var timer = document.getElementById('time');
  6. alert(typeof timer); //object
  7. console.log(timer);
  8. console.dir(timer);
  9. </script>
  10. </body>

根据标签名获取

  1. <body>
  2. <div id="time" class="ti">2022-4-11</div>
  3. <div>2022-4-12</div>
  4. <script>
  5. var timer = document.getElementsByTagName('div');
  6. console.log(timer); //object
  7. //返回的是伪数组,不支持push pop操作
  8. </script>
  9. </body>

document是获取页面上所有的

如何单独获取某个父标签下的子标签

  1. <body>
  2. <ol id="l1">
  3. <li></li>
  4. <li></li>
  5. <li></li>
  6. </ol>
  7. <script>
  8. var elements = document.getElementsByTagName('ol');
  9. var lis = elements[0].getElementsByTagName('li');
  10. console.log(lis);
  11. var l = document.getElementById('l1');
  12. var liss = l.getElementsByTagName('li');
  13. console.log(liss);
  14. </script>
  15. </body>

根据类名获取元素

var l = document.getElementsByClassName('box1');

指定选择器获取元素

querySelector        

指定选择器,可以是标签,类名或id。只返回符合条件的第一个元素

  1. <box class="box1" id="box11">a</box>
  2. var boxs = document.querySelector('#box11');
  3. var boxs = document.querySelector('.box1');

querySelectorAll

指定选择器,可以获取所有符合条件的元素

var boxs = document.querySelectorAll('.box1');

特殊元素获取

获取body和html

  1. //获取body
  2. var b = document.body;
  3. console.log(b);
  4. //获取html
  5. var h = document.documentElement;
  6. console.log(h);

三.事件

事件基础

事件由三部分组成:事件源,事件类型,事件处理程序

事件源:触发的对象,比如按钮

事件类型:如何触发,比如鼠标点击,鼠标经过等

事件处理程序:通过函数赋值的方式完成

  1. <body>
  2. <button id="btn">A</button>
  3. <script>
  4. var btn = document.getElementById('btn');
  5. btn.onclick = function () {
  6. alert("B");
  7. }
  8. </script>
  9. </body>

给多个事件源绑定事件

  1. <body>
  2. <button>A</button>
  3. <button>B</button>
  4. <button>C</button>
  5. <button>D</button>
  6. <button>E</button>
  7. <script>
  8. var btns = document.getElementsByTagName('button');
  9. for(var i = 0; i < btns.length; i++){
  10. btns[i].onclick = function (){
  11. //其他的按钮颜色失去
  12. for(var i = 0; i < btns.length; i++){
  13. btns[i].style.color = '';
  14. }
  15. //当前按钮颜色变色
  16. this.style.color = 'red';
  17. }
  18. }
  19. </script>
  20. </body>

 排他思想:首先先排除其他人,再设置自己的样式2

注册事件(绑定事件)

传统注册方式

利用on开头的,如onclick

= function(){}  这种方式一个元素同一个事件只能设置一个处理函数,后面的会覆盖掉前面的,因为这种方式是赋值方式

方法监听注册

同一个事件可以添加多个监听器

  1. <body>
  2. <button>tap me</button>
  3. <script>
  4. var btn = document.querySelector('button');
  5. btn.addEventListener('click',function(){
  6. alert('oops');
  7. })
  8. /*
  9. * 第一个参数 type 事件类型字符串 如click,mouseover
  10. * 第二个参数 listener 事件处理函数,当事件发生时,会调用改监听函数
  11. * 第三个参数 useCapture 可选参数,是一个布尔值,默认是false
  12. * */
  13. </script>
  14. </body>

删除事件(解绑事件)

传统注册方式

= null           赋值为null即可

方法监听注册

  1. <body>
  2. <button>tap me</button>
  3. <script>
  4. var btn = document.querySelector('button');
  5. btn.addEventListener('click',fn);
  6. function fn(){
  7. alert('oops');
  8. btn.removeEventListener('click',fn);
  9. }
  10. </script>

传入函数的时候需要传入有名字的函数,这样后面才能解绑。

DOM事件流

 事件流描述的是从页面中接收事件的顺序。

事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。

 给div注册事件,它的父节点们都会收到注册事件。

 

代码演示DOM流

演示1

点击son事件的顺序:son

  1. <body>
  2. <div class="father">
  3. <div class="son"></div>
  4. </div>
  5. <script>
  6. var son = document.querySelector('.son');
  7. //JS代码只能执行捕获或冒泡其中的一个阶段
  8. //onclick只能得到冒泡阶段
  9. //捕获阶段如果addEventListener第三个参数如果是true,则处于捕获阶段
  10. son.addEventListener('click',function (){
  11. alert('son');
  12. },true);
  13. //虽然给son添加了点击事件,但是document先得到点击,但是document没有函数,所以会没有执行效果
  14. </script>
  15. </body>

演示2

点击son事件出现的顺序:father-son

  1. <html lang="en">
  2. <head>
  3. <meta charset="UTF-8">
  4. <title>Title</title>
  5. <style>
  6. .son{
  7. width: 100px;
  8. height: 100px;
  9. background-color: green;
  10. }
  11. .father{
  12. width: 200px;
  13. height: 200px;
  14. background-color: salmon;
  15. }
  16. </style>
  17. </head>
  18. <body>
  19. <div class="father">
  20. <div class="son"></div>
  21. </div>
  22. <script>
  23. var son = document.querySelector('.son');
  24. //JS代码只能执行捕获或冒泡其中的一个阶段
  25. //onclick只能得到冒泡阶段
  26. //捕获阶段如果addEventListener第三个参数如果是true,则处于捕获阶段
  27. son.addEventListener('click',function (){
  28. alert('son');
  29. },true);
  30. var father = document.querySelector('.father');
  31. father.addEventListener('click',function (){
  32. alert('father');
  33. },true);
  34. //虽然给son添加了点击事件,但是document先得到点击,这里给father设置了点击事件,那么点击son,father先弹出
  35. </script>
  36. </body>
  37. </html>

如果添加事件的方法中的true改为false或不写,那么就事件流就处于冒泡阶段,先从son开始。

事件对象

  1. var son = document.querySelector('.son');
  2. son.onclick = function (event){
  3. //event是一个事件对象,当作形参来看,有了事件后,事件对象才存在,由系统自动创建,不需要我们传递参数
  4. //事件对象是我们事件的一系列相关数据的集合,跟事件相关的比如鼠标点击里面包含了鼠标的相关信息,鼠标坐标等
  5. console.log(event);
  6. }

  1. var son = document.querySelector('.son');
  2. son.addEventListener('click',function (event){ console.log(event);})

事件对象常见方法 

和this区别

:比如点击div触发了事件,那么就返回事件源的div

this:比如在ul中有很多li,给ul绑定事件,点击了li的话,this会返回ul而不是li,会返回li,因为this指向了被绑定的元素对象。

阻止默认行为

如让链接不跳转,让提交按钮不提交。

  1. var a = document.querySelector('a');
  2. a.addEventListener('click',function (e){
  3. e.preventDefault();
  4. })

;        return  false   也能阻止

阻止事件冒泡

  1. var a = document.querySelector('a');
  2. a.addEventListener('click',function (e){
  3. e.preventDefault();
  4. e.stopPropagation();
  5. })

在最下面一层设置阻止冒泡,就会停止向上冒泡了

= true 也可以

事件委托

事件冒泡可以应用的地方

 事件委托的原理:不是给每个子节点单独设置事件监听器,而是事件监听器设置在父节点上,然后利用冒泡原理影响设置每个子节点。

  1. <body>
  2. <ul>
  3. <li>A</li>
  4. <li>B</li>
  5. <li>C</li>
  6. <li>D</li>
  7. <li>E</li>
  8. </ul>
  9. <script>
  10. var ul = document.querySelector('ul');
  11. ul.addEventListener('click',function (e){
  12. alert('ABCDE');
  13. e.target.style.backgroundColor = 'pink';//点谁谁变色
  14. })
  15. </script>
  16. </body>

常见鼠标事件

 禁止鼠标右键菜单

contextmenu主要控制应该何时显示上下文菜单,主要用于取消默认上下文菜单

选中p中的文字无法右键

  1. <body>
  2. <p>我是一个PP</p>
  3. <script>
  4. var pp = document.querySelector('p');
  5. pp.addEventListener('contextmenu',function (e){
  6. e.preventDefault();
  7. })
  8. </script>
  9. </body>

禁止鼠标选中

  1. <body>
  2. <p>我是一个PP</p>
  3. <script>
  4. var pp = document.querySelector('p');
  5. pp.addEventListener('selectstart',function (e){
  6. e.preventDefault();
  7. })
  8. </script>
  9. </body>

鼠标事件对象

常见键盘事件

keypress区别大小写,keyup和keydown不区分大小写

 键盘事件对象

四.操作元素

1.操作元素内容 

操作元素的内容        innerText    或      innerHTML

  1. <button id="btn">A</button>
  2. var btn = document.getElementById('btn');
  3. btn.onclick = function (){
  4. btn.innerText = 'B';
  5. }

点击按钮,将A改成B

两者的区别

不识别HTML标签,innerHTML标签识别HTML标签

  1. var btn = document.getElementById('btn');
  2. btn.innerText = '<strong>C</strong>';//<strong>C</strong>
  3. btn.innerHTML = '<strong>C</strong>';//C

2.还可以获取内容,innerText 不识别标签,innerHTML识别标签,并且保留空格和换行。

  1. <p>
  2. 我是p
  3. <span>
  4. 我是span
  5. </span>
  6. </p>
  7. var btn = document.getElementById('btn');
  8. console.log(btn.innerText);
  1. <p>
  2. 我是p
  3. <span>
  4. 我是span
  5. </span>
  6. </p>
  7. var btn = document.getElementsByTagName('p');
  8. console.log(btn[0].innerHTML);

2.操作元素属性 

操作元素的属性

  1. <body>
  2. <p style="font-size:50px">
  3. 我是p
  4. <span>
  5. 我是span
  6. </span>
  7. </p>
  8. <script>
  9. var btn = document.getElementsByTagName('p');
  10. btn[0].style = "font-size:500px";
  11. </script>
  12. </body>

在通过获取的元素修改样式时,比如修改color,修改后的样式等于行内样式,所以会覆盖之前的样式

操作属性style的其他属性

  1. <body>
  2. <p>我是P</p>
  3. <script>
  4. var p = document.querySelector('p');
  5. p.style.color = 'red';
  6. </script>
  7. </body>

当要修改的属性多了起来,通过这种方式就会比较麻烦

  1. <html lang="en">
  2. <head>
  3. <meta charset="UTF-8">
  4. <title>Title</title>
  5. <style>
  6. .change{
  7. color:green;
  8. }
  9. </style>
  10. </head>
  11. <body>
  12. <p>我是P</p>
  13. <script>
  14. var p = document.querySelector('p');
  15. p.className = 'change';
  16. </script>
  17. </body>
  18. </html>

使用这种方式,先设置样式,再给标签更改类属性

  1. <html lang="en">
  2. <head>
  3. <meta charset="UTF-8">
  4. <title>Title</title>
  5. <style>
  6. .change{
  7. color:green;
  8. }
  9. .first{
  10. font-size: 50px;
  11. }
  12. </style>
  13. </head>
  14. <body>
  15. <p class="first">我是P</p>
  16. <script>
  17. var p = document.querySelector('p');
  18. p.className = p.className+' change';
  19. </script>
  20. </body>
  21. </html>

这样还可以保留以前的类的样式,也就是一个标签设置了多个类。

获取属性的属性值

  1. <body>
  2. <button class="bnt1" id="btn1">A</button>
  3. <button>B</button>
  4. <button>C</button>
  5. <button>D</button>
  6. <button>E</button>
  7. <script>
  8. var btn = document.querySelector('.bnt1');
  9. //方式1 element.属性
  10. alert(btn.id);
  11. alert(btn.className);
  12. //方式2 ('属性');
  13. alert(btn.getAttribute('class'));
  14. </script>
  15. </body>

两种方式的用法区别:

第一种方式只能获得内置的属性。

第二种方式还能获得自定义的属性。

这种属性是为了做区别用的,比如下面

<p index="1"></p>

设置属性值

  1. <body>
  2. <button class="btn1" id="btn1" index="1">A</button>
  3. <script>
  4. var btn = document.querySelector('.bnt1');
  5. //方式1 element.属性
  6. btn.className = 'btn';
  7. //方式2 ('属性','值');
  8. btn.setAttribute('index','0');
  9. </script>
  10. </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;//得到所有子节点,子节点包括元素节点,文本节点,空格等
  1. var pp = btn.children;//得到所有子节点,只包括元素节点
  2. var pp0 = btn.children[0];//得到第一个子节点
  1. var pp = btn.firstChild;//得到第一个子节点,不管是文本节点还是元素节点
  2. var ppp = btn.lastChild;//得到最后一个子节点,不管是文本节点还是元素节点
  3. var pp0 = btn.firstElementChild;//返回第一个元素节点
  4. var ppp0 = btn.lastElementChild;//返回最后一个元素节点

兄弟节点

  1. var next = btn.nextSibling;//下一个兄弟节点,不管是元素节点还是文本节点
  2. var previous = btn.previousSibling;//上一个兄弟节点,不管是元素节点还是文本节点
  3. var btn2 = btn.nextElementSibling;//下一个兄弟元素节点
  4. var btn0 = btn.previousElementSibling; //上一个兄弟元素节点

3.节点的操作

创建节点

比如添加评论的功能,添加了一个p,相当于添加了节点

只创建节点是没有效果的,还需要添加节点

添加节点

  1. <body>
  2. <ul id="u1">
  3. <li id="l1"></li>
  4. </ul>
  5. <script>
  6. //创建元素
  7. var li = document.createElement('li');
  8. //添加元素
  9. var ul = document.querySelector('#ul');
  10. ul.appendChild(li);//ul是父节点,li是子节点,将子节点放入到父节点种,追加的形式放入到父节点种
  11. ul.insertBefore(li,ul.children[0]);//在ul第一个子节点前面插入li
  12. </script>
  13. </body>

删除节点

  1. <body>
  2. <ul id="u1">
  3. <li id="l1">A</li>
  4. <li>B</li>
  5. <li>C</li>
  6. </ul>
  7. <script>
  8. var ul = document.querySelector('ul');
  9. ul.removeChild(ul.children[0]);
  10. </script>
  11. </body>

复制节点

  1. <body>
  2. <ul id="u1">
  3. <li id="l1">A</li>
  4. <li>B</li>
  5. <li>C</li>
  6. </ul>
  7. <script>
  8. var ul = document.querySelector('ul');
  9. var clone = ul.children[0].cloneNode();//如果括号的参数为空或false,就是浅拷贝,只克隆复制节点本身,不克隆里面的节点
  10. ul.appendChild(clone);
  11. var clone2 = ul.children[1].cloneNode(true);//克隆节点和节点的内容
  12. ul.appendChild(clone2);
  13. </script>
  14. </body>

六.案例

1.分时问候

根据时间不同,页面显示不同图片,显示不同问候语。

  1. <body>
  2. <img src="#" alt="">
  3. <div>上午好</div>
  4. <script>
  5. //1.获取元素
  6. var img = document.querySelector('img');
  7. var div = document.querySelector('div');
  8. //2.获取当前时间
  9. var date = new Date();
  10. var h = date.getHours();
  11. //3.判断
  12. if(h < 12 ){
  13. div.innerText = "上午好";
  14. }else if(h < 13){
  15. div.innerText = '中午好';
  16. }else if(h < 19){
  17. div.innerText = '下午好';
  18. }else {
  19. div.innerText = '晚上好';
  20. }
  21. </script>
  22. </body>

所用知识:

1.获取元素

2.获取时间,通过小时判断时段

3.修改元素内容,通过innerText修改标签内的内容

2.仿京东显示隐藏密码明文

注册账号时,密码输入栏中右侧按钮,单击显示密码,再点击显示*。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <script>
  7. </script>
  8. <style>
  9. .box{
  10. width: 400px;
  11. border-bottom: 1px solid #ccc;
  12. margin: 100px auto;
  13. }
  14. .box input{
  15. width: 370px;
  16. height: 30px;
  17. border: 10px;/*去掉未选中时显示的框*/
  18. outline: none;/*去掉选中后显示的框框*/
  19. }
  20. </style>
  21. </head>
  22. <body>
  23. <div class="box">
  24. <input type="password" id="pwd">
  25. <label for="pwd">
  26. <img src="../images/" alt="" width="18px" height="8px" id="eye">
  27. </label>
  28. </div>
  29. <script>
  30. //获取元素
  31. var img = document.querySelector('#eye');
  32. var pwd = document.querySelector('#pwd');
  33. var flag = 0;
  34. img.onclick = function (){
  35. if(flag == 0){
  36. flag = 1;
  37. img.src = "../images/";
  38. pwd.type = 'text';
  39. }else{
  40. flag = 0;
  41. img.src = "../images/";
  42. pwd.type = 'password';
  43. }
  44. }
  45. </script>
  46. </body>
  47. </html>

 所用知识:

1.获取元素

2.修改元素属性,通过修改input标签中的password和text属性来实现密码显示与隐藏。

3.仿淘宝关闭二维码

  1. <body>
  2. <div class="box">
  3. <img src="../images/" alt="" width="71px" height="68px">
  4. <i id="del">×</i>
  5. </div>
  6. <script>
  7. //获取元素
  8. var img = document.querySelector('img');
  9. var del = document.querySelector('#del');
  10. del.onclick = function (){
  11. // = true;
  12. img.style.display = 'none';
  13. }
  14. </script>
  15. </body>

两种隐藏方法都可以

点击×,图片隐藏起来 

4.循环精灵图        211

5.显示隐藏文本框的内容        212

6.密码框格式提示错误信息 214

7.百度换肤        217

8.表格隔行变色        218

9.表单全选取消        219+220

栏切换 223

11.新浪下拉菜单

碰到链接显示菜单

  1. <html lang="en">
  2. <head>
  3. <meta charset="UTF-8">
  4. <title>Title</title>
  5. <script src="jquery-3.4."></script>
  6. <script>
  7. $(function () {
  8. var nav = document.querySelector('.nav');
  9. var lis = nav.children;//得到四个li
  10. for(var i = 0; i < lis.length; i++){
  11. lis[i].onmouseover = function () {
  12. this.children[1].style.display = 'block';
  13. }
  14. lis[i].onmouseout = function (){
  15. this.children[1].style.display = 'none';
  16. }
  17. }
  18. })
  19. </script>
  20. <style>
  21. a{
  22. text-decoration: none;
  23. color:black;
  24. }
  25. .nav ul{
  26. display: none;
  27. width: 100%;
  28. }
  29. .nav>li{
  30. float: left;
  31. margin: 10px;
  32. }
  33. </style>
  34. </head>
  35. <body>
  36. <ul class="nav">
  37. <li>
  38. <a href="#">微博</a>
  39. <ul>
  40. <li>私信</li>
  41. <li>评论</li>
  42. <li>@我</li>
  43. </ul>
  44. </li>
  45. <li>
  46. <a href="#">微博</a>
  47. <ul>
  48. <li>私信</li>
  49. <li>评论</li>
  50. <li>@我</li>
  51. </ul>
  52. </li>
  53. <li>
  54. <a href="#">微博</a>
  55. <ul>
  56. <li>私信</li>
  57. <li>评论</li>
  58. <li>@我</li>
  59. </ul>
  60. </li>
  61. <li>
  62. <a href="#">微博</a>
  63. <ul>
  64. <li>私信</li>
  65. <li>评论</li>
  66. <li>@我</li>
  67. </ul>
  68. </li>
  69. </ul>
  70. </body>
  71. </html>

12.发布留言 234

13.删除留言 236

14.动态生成表格 238

15.跟随鼠标的天使 267

16.模拟京东输入内容案例