Web APIs 思考:
1 2 3 4 5 6 7 8 9 10 11 变量声明有三个 var let 和 const 我们应该用那个呢? 首先var 先排除,老派写法,问题很多,可以淘汰掉… let or const ? 建议: const 优先,尽量使用const,原因是: const 语义化更好 很多变量我们声明的时候就知道他不会被更改了,那为什么不用 const呢? 实际开发中也是,比如react框架,基本const 如果你还在纠结,那么我建议: 有了变量先给const,如果发现它后面是要被修改的,再改为let
1、作用与分类 作用: 就是使用 JS 去操作 html 和浏览器
分类:DOM (文档对象模型)、BOM(浏览器对象模型)
2、什么是DOM 1 2 3 4 5 DOM(Document Object Model——文档对象模型)是用来呈现以及与任意 HTML 或 XML文档交互的API 白话文:DOM是浏览器提供的一套专门用来 操作网页内容 的功能 DOM作用 开发网页内容特效和实现用户交互
3、DOM树 1 2 3 4 5 6 DOM树是什么 将 HTML 文档以树状结构直观的表现出来,我们称之为文档树或 DOM 树 描述网页内容关系的名词 作用:文档树直观的体现了标签与标签之间的关系
4、DOM对象(重要) 1 2 3 4 5 6 7 8 9 10 11 DOM对象:浏览器根据html标签生成的 JS对象 所有的标签属性都可以在这个对象上面找到 修改这个对象的属性会自动映射到标签身上 DOM的核心思想 把网页内容当做对象来处理 document 对象 是 DOM 里提供的一个对象 所以它提供的属性和方法都是用来访问和操作网页内容的 例:document.write() 网页所有内容都在document里面
1 2 3 4 5 6 7 8 <body> <div > 123</div > <script > const div = document .querySelector ('div' ) console .dir (div) </script > </body>
5、获取DOM对象 •根据CSS选择器来获取DOM元素
•其他获取DOM元素方法
5.1 根据CSS选择器来获取DOM元素 选择匹配的第一个元素
语法:
1 document .querySelector ('css 选择器' );
参数 :
包含一个或多个有效的CSS选择器 字符串
返回值:
CSS选择器匹配的第一个元素,一个 HTMLElement对象。
如果没有匹配到,则返回null。
选择匹配的多个元素
这里使用querySelectorAll
方法
1 document .querySelectorAll ('css 选择器' );
参数 :
包含一个或多个有效的CSS选择器 字符串
返回值:
CSS选择器匹配的NodeList 对象集合
例如:
1 document .querySelectorAll ('ul li' );
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 <!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 : 200px ; height : 200px ; } </style > </head > <body > <div class ="box" > 123</div > <div class ="box" > abc</div > <p id ="nav" > 导航栏</p > <ul class ="nav" > <li > 测试1</li > <li > 测试2</li > <li > 测试3</li > </ul > <script > const lis = document .querySelectorAll ('.nav li' ) for (let i = 0 ; i < lis.length ; i++) { console .log (lis[i]) } const p = document .querySelectorAll ('#nav' ) </script > </body > </html >
querySelectorAll
方法得到的是一个伪数组
伪数组:有长度有索引号,但是没有pop(),push()
等数组方法。
5.2 其他获取DOM
元素的方法 1 2 3 4 5 6 doucument.getElementById ('nav' ); document .getElementsByTagName ('div' );document .getElementsByClassName ('w' );
6、操作元素内容 1 2 3 对象.innerText 属性 对象.innerHTML 属性
1 2 3 4 元素innerText 属性 将文本内容添加/更新到任意标签位置 显示纯文本,不解析标签
1 2 3 4 元素.innerHTML 属性 将文本内容添加/更新到任意标签位置 会解析标签,多标签建议使用模板字符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <body> <div class ="box" > 我是文字的内容</div > <script > const box = document .querySelector ('.box' ) console .log (box.innerHTML ) box.innerHTML = '<strong>我要更换</strong>' </script > </body>
如果还在纠结到底用谁,你可以选择innerHTML
7、操作元素属性 7.1 操作元素常用属性 还可以通过 JS 设置/修改标签元素属性,比如通过 src更换 图片
最常见的属性比如: href、title、src 等
1 2 3 4 5 6 7 8 9 10 11 <body> <img src ="./images/1.webp" alt ="" > <script > const img = document .querySelector ('img' ) img.src = './images/2.webp' img.title = 'hello' </script > </body >
页面刷新,图片随机变换
7.2 操作元素样式 属性 1.通过 style 属性操作CSS
语法:对象.style.样式属性 = 值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <!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 : 200px ; height : 200px ; background-color : blue; } </style > </head > <body > <div class ="box" > </div > <script > const box = document .querySelector ('.box' ) box.style .width = '300px' box.style .backgroundColor = 'red' box.style .border = '2px solid blue' box.style .borderTop = '2px solid red' </script > </body > </html >
7.3 操作类名className操作CSS 如果修改的样式比较多,直接通过style属性修改比较繁琐,我们可以通过借助于css类名的形式。
语法:
1 2 元素.className = 'active'
注意:
1 2 3 由于class是关键字, 所以使用className去代替 className是使用新值换旧值, 如果需要添加一个类,需要保留之前的类名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <!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 : yellow; } .nav { color : red; } .box { width : 300px ; height : 300px ; background-color : skyblue; margin : 100px auto; padding : 10px ; border : 1px solid #000 ; } </style > </head > <body > <div class ="nav" > 123</div > <script > const div = document .querySelector ('div' ) div.className = 'nav box' </script > </body > </html >
注意:直接使用 className 赋值会覆盖以前的类名
7.4 通过classList
操作类控制css
为了解决className 容易覆盖以前的类名,我们可以通过classList方式追加和删除类名
语法:
1 2 3 4 5 6 // 追加一个类 元素.classList.add('类名'); // 删除一个类 元素.classList.remove('类名') // 切换一个类 元素.classList.toggle('类名')
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <!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 : 200px ; height : 200px ; color : #333 ; } .active { color : red; background-color : blue; } </style > </head > <body > <div class ="box " > 文字</div > <script > const box = document .querySelector ('.box' ) box.classList .toggle ('active' ) </script > </body > </html >
随机轮播图案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 <!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 > 轮播图点击切换</title > <style > * { box-sizing : border-box; } .slider { width : 560px ; height : 400px ; overflow : hidden; } .slider-wrapper { width : 100% ; height : 320px ; } .slider-wrapper img { width : 100% ; height : 100% ; display : block; } .slider-footer { height : 80px ; background-color : rgb (100 , 67 , 68 ); padding : 12px 12px 0 12px ; position : relative; } .slider-footer .toggle { position : absolute; right : 0 ; top : 12px ; display : flex; } .slider-footer .toggle button { margin-right : 12px ; width : 28px ; height : 28px ; appearance: none; border : none; background : rgba (255 , 255 , 255 , 0.1 ); color : #fff ; border-radius : 4px ; cursor : pointer; } .slider-footer .toggle button :hover { background : rgba (255 , 255 , 255 , 0.2 ); } .slider-footer p { margin : 0 ; color : #fff ; font-size : 18px ; margin-bottom : 10px ; } .slider-indicator { margin : 0 ; padding : 0 ; list-style : none; display : flex; align-items : center; } .slider-indicator li { width : 8px ; height : 8px ; margin : 4px ; border-radius : 50% ; background : #fff ; opacity : 0.4 ; cursor : pointer; } .slider-indicator li .active { width : 12px ; height : 12px ; opacity : 1 ; } </style > </head > <body > <div class ="slider" > <div class ="slider-wrapper" > <img src ="./images/slider01.jpg" alt ="" /> </div > <div class ="slider-footer" > <p > 对人类来说会不会太超前了?</p > <ul class ="slider-indicator" > <li > </li > <li > </li > <li > </li > <li > </li > <li > </li > <li > </li > <li > </li > <li > </li > </ul > <div class ="toggle" > <button class ="prev" > < </button > <button class ="next" > > </button > </div > </div > </div > <script > const sliderData = [ { url : './images/slider01.jpg' , title : '对人类来说会不会太超前了?' , color : 'rgb(100, 67, 68)' }, { url : './images/slider02.jpg' , title : '开启剑与雪的黑暗传说!' , color : 'rgb(43, 35, 26)' }, { url : './images/slider03.jpg' , title : '真正的jo厨出现了!' , color : 'rgb(36, 31, 33)' }, { url : './images/slider04.jpg' , title : '李玉刚:让世界通过B站看到东方大国文化' , color : 'rgb(139, 98, 66)' }, { url : './images/slider05.jpg' , title : '快来分享你的寒假日常吧~' , color : 'rgb(67, 90, 92)' }, { url : './images/slider06.jpg' , title : '哔哩哔哩小年YEAH' , color : 'rgb(166, 131, 143)' }, { url : './images/slider07.jpg' , title : '一站式解决你的电脑配置问题!!!' , color : 'rgb(53, 29, 25)' }, { url : './images/slider08.jpg' , title : '谁不想和小猫咪贴贴呢!' , color : 'rgb(99, 72, 114)' }, ] const random = parseInt (Math .random () * sliderData.length ) const img = document .querySelector ('.slider-wrapper img' ) img.src = sliderData[random].url const p = document .querySelector ('.slider-footer p' ) p.innerHTML = sliderData[random].title const footer = document .querySelector ('.slider-footer' ) footer.style .backgroundColor = sliderData[random].color const li = document .querySelector (`.slider-indicator li:nth-child(${random + 1 } )` ) li.classList .add ('active' ) </script > </body > </html >
7.5 操作表单元素 属性 表单很多情况,也需要修改属性
正常的有属性有取值的 跟其他的标签属性没有任何区别
1 2 3 获取: DOM对象.属性名 设置: DOM对象.属性名 = 新值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 <!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 > <input type ="checkbox" name ="" id ="" > <button > 点击</button > <script > const ipt = document .querySelector ('input' ) ipt.checked = true const button = document .querySelector ('button' ) button.disabled = true </script > </body > </html >
7.6 自定义属性 1 2 3 4 5 6 标准属性: 标签天生自带的属性 比如class id title等, 可以直接使用点语法操作比如: disabled、checked、selected 自定义属性: 在html5中推出来了专门的data-自定义属性 在标签上一律以data-开头 在DOM对象上一律以dataset对象方式获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <!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 data-id ="1" data-spm ="不知道" > 1</div > <div data-id ="2" > 2</div > <div data-id ="3" > 3</div > <div data-id ="4" > 4</div > <div data-id ="5" > 5</div > <script > const one = document .querySelector ('div' ) console .log (one.dataset .id ) console .log (one.dataset .spm ) </script > </body > </html >
8、定时器-间歇函数 1 2 3 4 5 网页中经常会需要一种功能:每隔一段时间需要自动执行一段代码,不需要我们手动去触发 例如:网页中的倒计时 要实现这种需求,需要定时器函数 定时器函数有两种,今天我先讲间歇函数
开启定时器
作用:每隔一段时间调用这个函数
间隔时间单位是毫秒
注意:
1.函数名字不需要加括号
2.定时器返回的是一个id 数字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <script> function fn ( ) { console .log ('一秒执行一次' ) } let n = setInterval (fn, 1000 ) console .log (n) clearInterval (n) let i = 1 setInterval (function ( ) { i++ document .write (`${i} ` ) }, 200 ) </script>
关闭定时器
1 2 let 变量名 = setInterval (函数,间隔时间)clearInterval (变量名);
一般都是满足了一定条件以后再停止
以下是:用户注册倒计时案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > Document</title > </head > <body > <textarea name ="" id ="" cols ="30" rows ="10" > 用户注册协议 欢迎注册成为京东用户!在您注册过程中,您需要完成我们的注册流程并通过点击同意的形式在线签署以下协议,请您务必仔细阅读、充分理解协议中的条款内容后再点击同意(尤其是以粗体或下划线标识的条款,因为这些条款可能会明确您应履行的义务或对您的权利有所限制)。 【请您注意】如果您不同意以下协议全部或任何条款约定,请您停止注册。您停止注册后将仅可以浏览我们的商品信息但无法享受我们的产品或服务。如您按照注册流程提示填写信息,阅读并点击同意上述协议且完成全部注册流程后,即表示您已充分阅读、理解并接受协议的全部内容,并表明您同意我们可以依据协议内容来处理您的个人信息,并同意我们将您的订单信息共享给为完成此订单所必须的第三方合作方(详情查看 </textarea > <br > <button class ="btn" disabled > 我已经阅读用户协议(5)</button > <script > const btn = document .querySelector ('.btn' ) let i = 5 let n = setInterval (function ( ) { i-- btn.innerHTML = `我已经阅读用户协议(${i} )` if (i === 0 ) { clearInterval (n) btn.disabled = false btn.innerHTML = '同意' } }, 1000 ) </script > </body > </html >
轮播图定时器案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 <!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 > 轮播图点击切换</title > <style > * { box-sizing : border-box; } .slider { width : 560px ; height : 400px ; overflow : hidden; } .slider-wrapper { width : 100% ; height : 320px ; } .slider-wrapper img { width : 100% ; height : 100% ; display : block; } .slider-footer { height : 80px ; background-color : rgb (100 , 67 , 68 ); padding : 12px 12px 0 12px ; position : relative; } .slider-footer .toggle { position : absolute; right : 0 ; top : 12px ; display : flex; } .slider-footer .toggle button { margin-right : 12px ; width : 28px ; height : 28px ; appearance: none; border : none; background : rgba (255 , 255 , 255 , 0.1 ); color : #fff ; border-radius : 4px ; cursor : pointer; } .slider-footer .toggle button :hover { background : rgba (255 , 255 , 255 , 0.2 ); } .slider-footer p { margin : 0 ; color : #fff ; font-size : 18px ; margin-bottom : 10px ; } .slider-indicator { margin : 0 ; padding : 0 ; list-style : none; display : flex; align-items : center; } .slider-indicator li { width : 8px ; height : 8px ; margin : 4px ; border-radius : 50% ; background : #fff ; opacity : 0.4 ; cursor : pointer; } .slider-indicator li .active { width : 12px ; height : 12px ; opacity : 1 ; } </style > </head > <body > <div class ="slider" > <div class ="slider-wrapper" > <img src ="./images/slider01.jpg" alt ="" /> </div > <div class ="slider-footer" > <p > 对人类来说会不会太超前了?</p > <ul class ="slider-indicator" > <li class ="active" > </li > <li > </li > <li > </li > <li > </li > <li > </li > <li > </li > <li > </li > <li > </li > </ul > <div class ="toggle" > <button class ="prev" > < </button > <button class ="next" > > </button > </div > </div > </div > <script > const sliderData = [ { url : './images/slider01.jpg' , title : '对人类来说会不会太超前了?' , color : 'rgb(100, 67, 68)' }, { url : './images/slider02.jpg' , title : '开启剑与雪的黑暗传说!' , color : 'rgb(43, 35, 26)' }, { url : './images/slider03.jpg' , title : '真正的jo厨出现了!' , color : 'rgb(36, 31, 33)' }, { url : './images/slider04.jpg' , title : '李玉刚:让世界通过B站看到东方大国文化' , color : 'rgb(139, 98, 66)' }, { url : './images/slider05.jpg' , title : '快来分享你的寒假日常吧~' , color : 'rgb(67, 90, 92)' }, { url : './images/slider06.jpg' , title : '哔哩哔哩小年YEAH' , color : 'rgb(166, 131, 143)' }, { url : './images/slider07.jpg' , title : '一站式解决你的电脑配置问题!!!' , color : 'rgb(53, 29, 25)' }, { url : './images/slider08.jpg' , title : '谁不想和小猫咪贴贴呢!' , color : 'rgb(99, 72, 114)' }, ] const img = document .querySelector ('.slider-wrapper img' ) const p = document .querySelector ('.slider-footer p' ) let i = 0 setInterval (function ( ) { i++ if (i >= sliderData.length ) { i = 0 } img.src = sliderData[i].url p.innerHTML = sliderData[i].title document .querySelector ('.slider-indicator .active' ).classList .remove ('active' ) document .querySelector (`.slider-indicator li:nth-child(${i + 1 } )` ).classList .add ('active' ) }, 1000 ) </script > </body > </html >
9、事件监听 什么是事件?
事件是在编程时系统内发生的动作 或者发生的事情
比如用户在网页上单击 一个按钮
什么是事件监听?
就是让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称为 绑定事件或者注册事件
比如鼠标经过显示下拉菜单,比如点击可以播放轮播图等等
语法:
1 元素对象.addEventListener ('事件类型' ,要执行的函数)
1 2 3 4 5 事件监听三要素: 事件源: 那个dom元素被事件触发了,要获取dom元素 事件类型: 用什么方式触发,比如鼠标单击 click、鼠标经过 mouseover 等 事件调用的函数: 要做什么事
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <body> <button > 点击</button > <script > const btn = document .querySelector ('button' ) btn.addEventListener ('click' , function ( ) { alert ('你早呀~' ) }) </script > </body>
案例:
需求:点击关闭之后,顶部关闭
分析:
①:点击的是关闭按钮
②:关闭的是父盒子
核心:利用样式的显示和隐藏完成, display:none 隐藏元素 display:block 显示元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 李伟兴 09:31:13 <!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 : 1000px ; height : 200px ; background-color : blue; margin : 100px auto; text-align : center; font-size : 50px ; line-height : 200px ; font-weight : 700 ; } .box1 { position : absolute; right : 20px ; top : 10px ; width : 20px ; height : 20px ; background-color : skyblue; text-align : center; line-height : 20px ; font-size : 16px ; cursor : pointer; } </style > </head > <body > <div class ="box" > 我是广告 <div class ="box1" > X</div > </div > <script > const box1 = document .querySelector ('.box1' ) const box = document .querySelector ('.box' ) box1.addEventListener ('click' , function ( ) { box.style .display = 'none' }) </script > </body > </html >
10、事件监听版本 1 2 3 4 5 6 7 DOM L0 事件源.on事件 = function() { } DOM L2 事件源.addEventListener(事件, 事件处理函数) 区别: on方式会被覆盖,addEventListener方式可绑定多次,拥有事件更多特性,推荐使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <body > <button > 点击</button > <script > const btn = document .querySelector ('button' ) btn.addEventListener ('click' , function ( ) { alert (11 ) }) btn.addEventListener ('click' , function ( ) { alert (22 ) }) </script > </body >
11、事件类型 鼠标事件
1 2 3 4 鼠标触发 click 鼠标点击 mouseenter 鼠标经过mouseleave 鼠标离开
焦点事件
1 2 3 4 表单获得光标 focus 获得焦点 blur 失去焦点
键盘事件
1 2 3 4 键盘触发 Keydown 键盘按下触发 Keyup 键盘抬起触发
文本事件
轮播图完整案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 <!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 > 轮播图点击切换</title > <style > * { box-sizing : border-box; } .slider { width : 560px ; height : 400px ; overflow : hidden; } .slider-wrapper { width : 100% ; height : 320px ; } .slider-wrapper img { width : 100% ; height : 100% ; display : block; } .slider-footer { height : 80px ; background-color : rgb (100 , 67 , 68 ); padding : 12px 12px 0 12px ; position : relative; } .slider-footer .toggle { position : absolute; right : 0 ; top : 12px ; display : flex; } .slider-footer .toggle button { margin-right : 12px ; width : 28px ; height : 28px ; appearance: none; border : none; background : rgba (255 , 255 , 255 , 0.1 ); color : #fff ; border-radius : 4px ; cursor : pointer; } .slider-footer .toggle button :hover { background : rgba (255 , 255 , 255 , 0.2 ); } .slider-footer p { margin : 0 ; color : #fff ; font-size : 18px ; margin-bottom : 10px ; } .slider-indicator { margin : 0 ; padding : 0 ; list-style : none; display : flex; align-items : center; } .slider-indicator li { width : 8px ; height : 8px ; margin : 4px ; border-radius : 50% ; background : #fff ; opacity : 0.4 ; cursor : pointer; } .slider-indicator li .active { width : 12px ; height : 12px ; opacity : 1 ; } </style > </head > <body > <div class ="slider" > <div class ="slider-wrapper" > <img src ="./images/slider01.jpg" alt ="" /> </div > <div class ="slider-footer" > <p > 对人类来说会不会太超前了?</p > <ul class ="slider-indicator" > <li class ="active" > </li > <li > </li > <li > </li > <li > </li > <li > </li > <li > </li > <li > </li > <li > </li > </ul > <div class ="toggle" > <button class ="prev" > < </button > <button class ="next" > > </button > </div > </div > </div > <script > const data = [ { url : './images/slider01.jpg' , title : '对人类来说会不会太超前了?' , color : 'rgb(100, 67, 68)' }, { url : './images/slider02.jpg' , title : '开启剑与雪的黑暗传说!' , color : 'rgb(43, 35, 26)' }, { url : './images/slider03.jpg' , title : '真正的jo厨出现了!' , color : 'rgb(36, 31, 33)' }, { url : './images/slider04.jpg' , title : '李玉刚:让世界通过B站看到东方大国文化' , color : 'rgb(139, 98, 66)' }, { url : './images/slider05.jpg' , title : '快来分享你的寒假日常吧~' , color : 'rgb(67, 90, 92)' }, { url : './images/slider06.jpg' , title : '哔哩哔哩小年YEAH' , color : 'rgb(166, 131, 143)' }, { url : './images/slider07.jpg' , title : '一站式解决你的电脑配置问题!!!' , color : 'rgb(53, 29, 25)' }, { url : './images/slider08.jpg' , title : '谁不想和小猫咪贴贴呢!' , color : 'rgb(99, 72, 114)' }, ] const img = document .querySelector ('.slider-wrapper img' ) const p = document .querySelector ('.slider-footer p' ) const footer = document .querySelector ('.slider-footer' ) const next = document .querySelector ('.next' ) let i = 0 next.addEventListener ('click' , function ( ) { i++ i = i >= data.length ? 0 : i toggle () }) const prev = document .querySelector ('.prev' ) prev.addEventListener ('click' , function ( ) { i-- i = i < 0 ? data.length - 1 : i toggle () }) function toggle ( ) { img.src = data[i].url p.innerHTML = data[i].title footer.style .backgroundColor = data[i].color document .querySelector ('.slider-indicator .active' ).classList .remove ('active' ) document .querySelector (`.slider-indicator li:nth-child(${i + 1 } )` ).classList .add ('active' ) } let timerId = setInterval (function ( ) { next.click () }, 1000 ) const slider = document .querySelector ('.slider' ) slider.addEventListener ('mouseenter' , function ( ) { clearInterval (timerId) }) slider.addEventListener ('mouseleave' , function ( ) { if (timerId) clearInterval (timerId) timerId = setInterval (function ( ) { next.click () }, 1000 ) }) </script > </body > </html >
焦点事件演示:
1 2 3 4 5 6 7 8 9 10 11 12 <body > <input type ="text" > <script > const input = document .querySelector ('input' ) input.addEventListener ('focus' , function ( ) { console .log ('有焦点触发' ) }) input.addEventListener ('blur' , function ( ) { console .log ('失去焦点触发' ) }) </script > </body >
小米搜索框案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 <!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-sizing : border-box; } ul { list-style : none; } .mi { position : relative; width : 223px ; margin : 100px auto; } .mi input { width : 223px ; height : 48px ; padding : 0 10px ; font-size : 14px ; line-height : 48px ; border : 1px solid #e0e0e0 ; outline : none; } .mi .search { border : 1px solid #ff6700 ; } .result-list { display : none; position : absolute; left : 0 ; top : 48px ; width : 223px ; border : 1px solid #ff6700 ; border-top : 0 ; background : #fff ; } .result-list a { display : block; padding : 6px 15px ; font-size : 12px ; color : #424242 ; text-decoration : none; } .result-list a :hover { background-color : #eee ; } </style > </head > <body > <div class ="mi" > <input type ="search" placeholder ="小米笔记本" > <ul class ="result-list" > <li > <a href ="#" > 全部商品</a > </li > <li > <a href ="#" > 小米11</a > </li > <li > <a href ="#" > 小米10S</a > </li > <li > <a href ="#" > 小米笔记本</a > </li > <li > <a href ="#" > 小米手机</a > </li > <li > <a href ="#" > 黑鲨4</a > </li > <li > <a href ="#" > 空调</a > </li > </ul > </div > <script > const input = document .querySelector ('[type=search]' ) const ul = document .querySelector ('.result-list' ) input.addEventListener ('focus' , function ( ) { ul.style .display = 'block' input.classList .add ('search' ) }) input.addEventListener ('blur' , function ( ) { ul.style .display = 'none' input.classList .remove ('search' ) }) </script > </body > </html >
键盘事件演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <body > <input type ="text" > <script > const input = document .querySelector ('input' ) input.addEventListener ('input' , function ( ) { console .log (input.value ) }) </script > </body >
评论字数统计案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 <!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 > 评论回车发布</title > <style > .wrapper { min-width : 400px ; max-width : 800px ; display : flex; justify-content : flex-end; } .avatar { width : 48px ; height : 48px ; border-radius : 50% ; overflow : hidden; background : url (./images/avatar.jpg ) no-repeat center / cover; margin-right : 20px ; } .wrapper textarea { outline : none; border-color : transparent; resize : none; background : #f5f5f5 ; border-radius : 4px ; flex : 1 ; padding : 10px ; transition : all 0.5s ; height : 30px ; } .wrapper textarea :focus { border-color : #e4e4e4 ; background : #fff ; height : 50px ; } .wrapper button { background : #00aeec ; color : #fff ; border : none; border-radius : 4px ; margin-left : 10px ; width : 70px ; cursor : pointer; } .wrapper .total { margin-right : 80px ; color : #999 ; margin-top : 5px ; opacity : 0 ; transition : all 0.5s ; } .list { min-width : 400px ; max-width : 800px ; display : flex; } .list .item { width : 100% ; display : flex; } .list .item .info { flex : 1 ; border-bottom : 1px dashed #e4e4e4 ; padding-bottom : 10px ; } .list .item p { margin : 0 ; } .list .item .name { color : #FB7299 ; font-size : 14px ; font-weight : bold; } .list .item .text { color : #333 ; padding : 10px 0 ; } .list .item .time { color : #999 ; font-size : 12px ; } </style > </head > <body > <div class ="wrapper" > <i class ="avatar" > </i > <textarea id ="tx" placeholder ="发一条友善的评论" rows ="2" maxlength ="200" > </textarea > <button > 发布</button > </div > <div class ="wrapper" > <span class ="total" > 0/200字</span > </div > <div class ="list" > <div class ="item" style ="display: none;" > <i class ="avatar" > </i > <div class ="info" > <p class ="name" > 清风徐来</p > <p class ="text" > 大家都辛苦啦,感谢各位大大的努力,能圆满完成真是太好了[笑哭][支持]</p > <p class ="time" > 2022-10-10 20:29:21</p > </div > </div > </div > <script > const tx = document .querySelector ('#tx' ) const total = document .querySelector ('.total' ) tx.addEventListener ('focus' , function ( ) { total.style .opacity = 1 }) tx.addEventListener ('blur' , function ( ) { total.style .opacity = 0 }) tx.addEventListener ('input' , function ( ) { total.innerHTML = `${tx.value.length} /200字` }) </script > </body > </html >
12、事件对象 12.1 获取事件对象 1 2 3 4 5 6 7 事件对象是什么 也是个对象,这个对象里有事件触发时的相关信息 例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息 使用场景 可以判断用户按下哪个键,比如按下回车键可以发布新闻 可以判断鼠标点击了哪个元素,从而做相应的操作
语法:
在事件绑定的回调函数的第一个参数就是事件对象
一般命名为event、ev、e
1 2 3 元素.addEventListener ('click' ,function (e ){ })
12.2 事件对象常用属性 1 2 3 4 5 6 7 8 9 10 11 部分常用属性 type 获取当前的事件类型 clientX/clientY 获取光标相对于浏览器可见窗口左上角的位置 offsetX/offsetY 获取光标相对于当前DOM元素左上角的位置 key 用户按下的键盘键的值 现在不提倡使用keyCode
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <!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 > <input type ="text" > <script > const input = document .querySelector ('input' ) input.addEventListener ('keyup' , function (e ) { if (e.key === 'Enter' ) { console .log ('我按下了回车键' ) } }) </script > </body > </html >
评论回车发布案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 <!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 > 评论回车发布</title > <style > .wrapper { min-width : 400px ; max-width : 800px ; display : flex; justify-content : flex-end; } .avatar { width : 48px ; height : 48px ; border-radius : 50% ; overflow : hidden; background : url (./images/avatar.jpg ) no-repeat center / cover; margin-right : 20px ; } .wrapper textarea { outline : none; border-color : transparent; resize : none; background : #f5f5f5 ; border-radius : 4px ; flex : 1 ; padding : 10px ; transition : all 0.5s ; height : 30px ; } .wrapper textarea :focus { border-color : #e4e4e4 ; background : #fff ; height : 50px ; } .wrapper button { background : #00aeec ; color : #fff ; border : none; border-radius : 4px ; margin-left : 10px ; width : 70px ; cursor : pointer; } .wrapper .total { margin-right : 80px ; color : #999 ; margin-top : 5px ; opacity : 0 ; transition : all 0.5s ; } .list { min-width : 400px ; max-width : 800px ; display : flex; } .list .item { width : 100% ; display : flex; } .list .item .info { flex : 1 ; border-bottom : 1px dashed #e4e4e4 ; padding-bottom : 10px ; } .list .item p { margin : 0 ; } .list .item .name { color : #FB7299 ; font-size : 14px ; font-weight : bold; } .list .item .text { color : #333 ; padding : 10px 0 ; } .list .item .time { color : #999 ; font-size : 12px ; } </style > </head > <body > <div class ="wrapper" > <i class ="avatar" > </i > <textarea id ="tx" placeholder ="发一条友善的评论" rows ="2" maxlength ="200" > </textarea > <button > 发布</button > </div > <div class ="wrapper" > <span class ="total" > 0/200字</span > </div > <div class ="list" > <div class ="item" style ="display: none;" > <i class ="avatar" > </i > <div class ="info" > <p class ="name" > 清风徐来</p > <p class ="text" > 大家都辛苦啦,感谢各位大大的努力,能圆满完成真是太好了[笑哭][支持]</p > <p class ="time" > 2022-10-10 20:29:21</p > </div > </div > </div > <script > const tx = document .querySelector ('#tx' ) const total = document .querySelector ('.total' ) const item = document .querySelector ('.item' ) const text = document .querySelector ('.text' ) tx.addEventListener ('focus' , function ( ) { total.style .opacity = 1 }) tx.addEventListener ('blur' , function ( ) { total.style .opacity = 0 }) tx.addEventListener ('input' , function ( ) { total.innerHTML = `${tx.value.length} /200字` }) tx.addEventListener ('keyup' , function (e ) { if (e.key === 'Enter' ) { if (tx.value .trim ()) { item.style .display = 'block' text.innerHTML = tx.value } tx.value = '' total.innerHTML = '0/200字' } }) </script > </body > </html >
13、环境对象 1 2 3 4 5 6 环境对象:指的是函数内部特殊的变量 this ,它代表着当前函数运行时所处的环境 作用:弄清楚this的指向,可以让我们代码更简洁 函数的调用方式不同,this 指代的对象也不同 【谁调用, this 就是谁】 是判断 this 指向的粗略规则 直接调用函数,其实相当于是 window.函数,所以 this 指代 window
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <body > <button > 点击</button > <script > const btn = document .querySelector ('button' ) btn.addEventListener ('click' , function ( ) { this .style .color = 'red' }) </script > </body > </html >
回调函数说明
1 2 3 4 如果将函数 A 做为参数传递给函数 B 时,我们称函数 A 为回调函数 简单理解: 当一个函数当做参数来传递给另外一个函数的时候,这个函数就是回调函数 常见的使用场景:
全选复选框案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 <!DOCTYPE html > <html > <head lang ="en" > <meta charset ="UTF-8" > <title > </title > <style > * { margin : 0 ; padding : 0 ; } table { border-collapse : collapse; border-spacing : 0 ; border : 1px solid #c0c0c0 ; width : 500px ; margin : 100px auto; text-align : center; } th { background-color : #09c ; font : bold 16px "微软雅黑" ; color : #fff ; height : 24px ; } td { border : 1px solid #d0d0d0 ; color : #404060 ; padding : 10px ; } .allCheck { width : 80px ; } </style > </head > <body > <table > <tr > <th class ="allCheck" > <input type ="checkbox" name ="" id ="checkAll" > <span class ="all" > 全选</span > </th > <th > 商品</th > <th > 商家</th > <th > 价格</th > </tr > <tr > <td > <input type ="checkbox" name ="check" class ="ck" > </td > <td > 小米手机</td > <td > 小米</td > <td > ¥1999</td > </tr > <tr > <td > <input type ="checkbox" name ="check" class ="ck" > </td > <td > 小米净水器</td > <td > 小米</td > <td > ¥4999</td > </tr > <tr > <td > <input type ="checkbox" name ="check" class ="ck" > </td > <td > 小米电视</td > <td > 小米</td > <td > ¥5999</td > </tr > </table > <script > const checkAll = document .querySelector ('#checkAll' ) const cks = document .querySelectorAll ('.ck' ) checkAll.addEventListener ('click' , function ( ) { for (let i = 0 ; i < cks.length ; i++) { cks[i].checked = this .checked } }) for (let i = 0 ; i < cks.length ; i++) { cks[i].addEventListener ('click' , function ( ) { checkAll.checked = document .querySelectorAll ('.ck:checked' ).length === cks.length }) } </script > </body > </html >
14、事件流 事件流指的是事件完整执行过程中的流动路径
说明:假设页面里有个div,当触发事件时,会经历两个阶段,分别是捕获阶段、冒泡阶段
简单来说:捕获阶段是 从父到子 冒泡阶段是从子到父
实际工作都是使用事件冒泡为主
14.1 事件捕获 概念:从DOM
的根元素开始去执行对应的事件 (从外到里)
代码:
1 Dom .addEventListener (事件类型,事件处理函数,是否使用捕获机制)
说明:
1 2 3 4 addEventListener第三个参数传入 true 代表是捕获阶段触发(很少使用) 若传入false代表冒泡阶段触发,默认就是false 若是用 L0 事件监听,则只有冒泡阶段,没有捕获
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 <!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 > .father { width : 500px ; height : 500px ; background-color : blue; } .son { width : 200px ; height : 200px ; background-color : purple; } </style > </head > <body > <div class ="father" > <div class ="son" > </div > </div > <script > const fa = document .querySelector ('.father' ) const son = document .querySelector ('.son' ) document .addEventListener ('click' , function ( ) { alert ('我是爷爷' ) }, true ) fa.addEventListener ('click' , function ( ) { alert ('我是爸爸' ) }, true ) son.addEventListener ('click' , function ( ) { alert ('我是儿子' ) }, true ) </script > </body > </html >
14.2 事件冒泡 当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒泡
简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的 同名事件
事件冒泡是默认存在的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 <!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> .father { width: 500px; height: 500px; background-color: blue; } .son { width: 200px; height: 200px; background-color: purple; } </style> </head> <body> <div class="father"> <div class="son"></div> </div> <script> const fa = document.querySelector('.father') const son = document.querySelector('.son') document.addEventListener('click', function () { alert('我是爷爷') }) fa.addEventListener('click', function () { alert('我是爸爸') }) son.addEventListener('click', function (e) { alert('我是儿子') // 阻止流动传播 事件对象.stopPropagation() e.stopPropagation() }) </script> </body> </html>
14.3 阻止冒泡 因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素
若想把事件就限制在当前元素内,就需要阻止事件冒泡
阻止事件冒泡需要拿到事件对象
事件对象.stopPropagation()
14.4 阻止默认行为 我们某些情况下需要 阻止默认行为的发生,比如 阻止 链接的跳转,表单域跳转
语法:
14.5 解绑事件 on事件方式,直接使用null覆盖偶就可以实现事件的解绑
addEventListener方式,必须使用:
removeEventListener(事件类型, 事件处理函数, [获取捕获或者冒泡阶段])
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <body> <button > 点击</button > <script > const btn = document .querySelector ('button' ) function fn ( ) { alert ('点击了' ) } btn.addEventListener ('click' , fn) btn.removeEventListener ('click' , fn) </script > </body>
注意:匿名函数无法被解绑
14.6 鼠标经过事件的区别 1 2 3 4 鼠标经过事件: mouseover 和 mouseout 会有冒泡效果 mouseenter 和 mouseleave 没有冒泡效果 (推荐)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 <!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 > .dad { width : 400px ; height : 400px ; background-color : blue; } .baby { width : 200px ; height : 200px ; background-color : purple; } </style > </head > <body > <div class ="dad" > <div class ="baby" > </div > </div > <script > const dad = document .querySelector ('.dad' ) const baby = document .querySelector ('.baby' ) baby.addEventListener ('mouseover' , function ( ) { console .log ('鼠标经过' ) }) baby.addEventListener ('mouseout' , function ( ) { console .log ('鼠标离开' ) }) dad.addEventListener ("mouseover" ,function ( ){ console .log ('dad' ); }) dad.addEventListener ("mouseout" ,function ( ){ console .log ("dad hello" ); }) </script > </body > </html >
这里指定的mouseout,mouseover
会有冒泡效果。
14.7 两种注册事件的区别 1 2 3 4 5 6 7 8 9 10 11 传统on注册(L0) 同一个对象,后面注册的事件会覆盖前面注册(同一个事件) 直接使用null覆盖偶就可以实现事件的解绑 都是冒泡阶段执行的 事件监听注册(L2) 语法: addEventListener(事件类型, 事件处理函数, 是否使用捕获) 后面注册的事件不会覆盖前面注册的事件(同一个事件) 可以通过第三个参数去确定是在冒泡或者捕获阶段执行 必须使用removeEventListener(事件类型, 事件处理函数, 获取捕获或者冒泡阶段) 匿名函数无法被解绑
15、事件委托 1.如果同时给多个元素注册事件,我们怎么做的?
for循环注册事件
2.有没有一种技巧 注册一次事件就能完成以上效果呢?
事件委托是利用事件流的特征解决一些开发需求的知识技巧
优点:减少注册次数,可以提高程序性能
原理:事件委托其实是利用事件冒泡的特点。
1 2 给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <!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 > <ul > <li > 第1个孩子</li > <li > 第2个孩子</li > <li > 第3个孩子</li > <li > 第4个孩子</li > <li > 第5个孩子</li > <p > 我不需要变色</p > </ul > <script > const ul = document .querySelector ('ul' ) ul.addEventListener ('click' , function (e ) { if (e.target .tagName === 'LI' ) { e.target .style .color = 'red' } }) </script > </body > </html >
16、其他事件 16.1 页面加载事件 加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件
应用场景:
(1)有些时候需要等页面资源全部处理完了做一些事情
(2)老代码喜欢把 script 写在 head 中,这时候直接找 dom 元素找不到
事件名称:load
监听页面所有资源加载完毕:
给window
添加load
事件
1 2 3 window .addEventListener ('load' ,function ( ){ })
注意:不光可以监听整个页面资源加载完毕,也可以针对某个资源绑定load事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <!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 > <script > document .addEventListener ('DOMContentLoaded' , function ( ) { const btn = document .querySelector ('button' ) btn.addEventListener ('click' , function ( ) { alert (11 ) }) }) </script > </head > <body > <button > 点击</button > </body > </html >
当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像等完全加载
事件名:DOMContentLoaded
监听页面DOM加载完毕:
给 document 添加 DOMContentLoaded 事件
16.2 页面滚动事件 滚动条在滚动的时候持续触发的事件
很多网页需要检测用户把页面滚动到某个区域后做一些处理, 比如固定导航栏,比如返回顶部
事件名:scroll
监听整个页面滚动
1 2 3 window .addEventListener ('scroll' ,function ( ){})
监听某个元素的内部滚动直接给某个元素加即可
使用场景:
我们想要页面滚动一段距离,比如100px,就让某些元素
显示隐藏,那我们怎么知道,页面滚动了100像素呢?
就可以使用scroll 来检测滚动的距离~~~
16.2.1 页面滚动事件-获取位置 1 2 3 4 5 scrollLeft和scrollTop (属性) 获取被卷去的大小 获取元素内容往左、往上滚出去看不到的距离 这两个值是可读写的 尽量在scroll事件里面获取被卷去的距离
开发中,我们经常检测页面滚动的距离,比如页面滚动100像素,就可以显示一个元素,或者固定一个元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 <!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 > body { padding-top : 100px ; height : 3000px ; } div { display : none; margin : 100px ; overflow : scroll; width : 200px ; height : 200px ; border : 1px solid #000 ; } </style > </head > <body > <div > 我里面有很多很多的文字 我里面有很多很多的文字 我里面有很多很多的文字 我里面有很多很多的文字 我里面有很多很多的文字 我里面有很多很多的文字 我里面有很多很多的文字 我里面有很多很多的文字 我里面有很多很多的文字 我里面有很多很多的文字 我里面有很多很多的文字 我里面有很多很多的文字 我里面有很多很多的文字 我里面有很多很多的文字 </div > <script > const div = document .querySelector ('div' ) window .addEventListener ('scroll' , function ( ) { const n = document .documentElement .scrollTop if (n >= 100 ) { div.style .display = 'block' } else { div.style .display = 'none' } }) </script > </body > </html >
scrollTop
细节
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <!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 > body { height : 3000px ; } </style > </head > <body > <script > document .documentElement .scrollTop = 800 window .addEventListener ('scroll' , function ( ) { const n = document .documentElement .scrollTop console .log (n) }) </script > </body > </html >
16.3 页面尺寸事件 会在窗口尺寸改变的时候触发事件:
resize
1 2 3 window .addEventListener ('resize' ,function ( ){})
获取元素的可见部分宽高(不包含边框,margin,滚动条等)
clientWidth和clientHeight
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <!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 { display : inline-block; height : 200px ; background-color : blue; padding : 10px ; border : 20px solid red; } </style > </head > <body > <div > 123123123123123123123123123123123123123</div > <script > const div = document .querySelector ('div' ) console .log (div.clientWidth ) window .addEventListener ('resize' , function ( ) { console .log (1 ) }) </script > </body > </html >
17、日期对象 作用:可以得到当前系统时间
在代码中发现了 new 关键字时,一般将这个操作称为实例化
创建一个时间对象并获取时间。
获取当前时间
获取指定时间
1 2 const date = new Date ('2022-2-2' )console .log (date);
1 2 3 4 5 6 7 8 9 <script> const date = new Date () console .log (date.getFullYear ()) console .log (date.getMonth () + 1 ) console .log (date.getDate ()) console .log (date.getDay ()) </script>
显示格式化的日期时间案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 <!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 : 300px ; height : 40px ; border : 1px solid blue; text-align : center; line-height : 40px ; } </style > </head > <body > <div > </div > <script > const div = document .querySelector ('div' ) function getMyDate ( ) { const date = new Date () let h = date.getHours () let m = date.getMinutes () let s = date.getSeconds () h = h < 10 ? '0' + h : h m = m < 10 ? '0' + m : m s = s < 10 ? '0' + s : s return `今天是: ${date.getFullYear()} 年${date.getMonth() + 1 } 月${date.getDate()} 号 ${h} :${m} :${s} ` } div.innerHTML = getMyDate () setInterval (function ( ) { div.innerHTML = getMyDate () }, 1000 ) </script > </body > </html >
18、节点操作 DOM节点:DOM树里每一个内容都称之为节点
1 2 3 4 5 6 节点类型 元素节点:所有的标签 比如 body、 div,html 是根节点 属性节点:所有的属性,比如href等 文本节点:所有的文本
18.1 查找节点 节点关系
父节点查找
通过parentNode
属性进行查找,返回最近一级的父节点,找不到返回的是null
1 2 3 4 5 6 7 8 9 10 11 12 13 <body > <div class ="yeye" > <div class ="dad" > <div class ="baby" > x </div > </div > </div > <script > const baby = document .querySelector ('.baby' ) console .log (baby) console .log (baby.parentNode ) console .log (baby.parentNode .parentNode ) </script > </body >
子节点查找
childNodes
: 获得所有子节点、包括文本节点(空格、换行)、注释节点等
children 属性 (重点) : 仅获取所有元素节点,返回的是一个伪数组
兄弟关系查找:
1 2 3 4 5 1. 下一个兄弟节点 nextElementSibling 属性 2. 上一个兄弟节点 previousElementSibling 属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <body > <ul > <li > 1</li > <li > 2</li > <li > 3</li > <li > 4</li > <li > 5</li > </ul > <script > const li2 = document .querySelector ('ul li:nth-child(2)' ) console .log (li2.previousElementSibling ) console .log (li2.nextElementSibling ) </script > </body >
18.2 增加节点 l即创造出一个新的网页元素,再添加到网页内,一般先创建节点,然后插入节点
创建元素节点方法:
1 2 document .createElement ('标签名' )
要想在界面看到,还得插入到某个父元素中
插入到父元素的最后一个子元素:
1 2 3 4 5 父元素.appendChild (要插入的元素) 父元素.insertBefore (要插入的元素,在哪个元素前面)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <body > <ul > <li > 我是老大</li > </ul > <script > const ul = document .querySelector ('ul' ) const li = document .createElement ('li' ) li.innerHTML = '我是li' ul.insertBefore (li, ul.children [0 ]) </script > </body >
克隆节点
特殊情况下,我们新增节点,按照如下操作:
1 2 3 复制一个原有的节点 把复制的节点放入到指定的元素内部
1 2 3 4 5 cloneNode会克隆出一个跟原标签一样的元素,括号内传入布尔值 若为true,则代表克隆时会包含后代节点一起克隆 若为false,则代表克隆时不包含后代节点 默认为false
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <body > <ul > <li > 1</li > <li > 2</li > <li > 3</li > </ul > <script > const ul = document .querySelector ('ul' ) ul.appendChild (ul.children [0 ].cloneNode (true )) </script > </body >
18.3 删除节点 若一个节点在页面中已不需要时,可以删除它
在 JavaScript 原生DOM操作中,要删除元素必须通过父元素删除
语法:
如不存在父子关系则删除不成功
删除节点和隐藏节点(display:none) 有区别的: 隐藏节点还是存在的,但是删除,则从html中删除节点
1 2 3 4 5 6 7 8 9 10 11 12 <body > <div class ="box" > 123</div > <ul > <li > 没用了</li > </ul > <script > const ul = document .querySelector ('ul' ) ul.removeChild (ul.children [0 ]) </script > </body >
19、Window
对象 19.1 BOM
BOM(Browser Object Model ) 是浏览器对象模型
1 2 3 4 5 6 7 8 window对象是一个全局对象,也可以说是JavaScript中的顶级对象 像document、alert()、console.log()这些都是window的属性,基本BOM的属性和方法都是window的。 所有通过var定义在全局作用域中的变量、函数都会变成window对象的属性和方法 window对象下的属性和方法调用的时候可以省略window location: 浏览器地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <body > <script > console .log (document === window .document ) function fn ( ) { console .log (11 ) } window .fn () var num = 10 console .log (window .num ) </script > </body >
19.2 定时器-延时函数 JavaScript
内置的一个用来让代码延迟执行的函数,叫 setTimeout
语法:
setTimeout 仅仅只执行一次,所以可以理解为就是把一段代码延迟执行, 平时省略window
清除延时函数
1 2 let timer = setTimeout (回调函数,等待的毫秒数)clearTimeout (timer)
1 2 3 4 两种定时器对比:执行的次数 延时函数: 执行一次 间歇函数:每隔一段时间就执行一次,除非手动清除
1 2 3 4 5 6 7 8 <body > <script > setTimeout (function ( ) { console .log ('时间到了' ) }, 2000 ) </script > </body >
19.3 JS
执行机制 JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。
这是因为 Javascript 这门脚本语言诞生的使命所致——JavaScript 是为处理页面中用户的交互,以及操作 DOM 而诞生的。比如我们对某个 DOM 元素进行添加和删除操作,不能同时进行。 应该先进行添加,之后再删除。
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是: 如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程。于是,JS 中出现了同步和异步。
同步
前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。比如做饭的同步做法:我们要烧水煮饭,等水开了(10分钟之后),再去切菜,炒菜。
异步
你在做一件事情时,因为这件事情会花费很长时间,在做这件事的同时,你还可以去处理其他事情。比如做饭的异步做法,我们在烧水的同时,利用这10分钟,去切菜,炒菜。
同步任务
同步任务都在主线程上执行,形成一个执行栈。
异步任务
JS 的异步是通过回调函数实现的。
一般而言,异步任务有以下三种类型:
1、普通事件,如 click、resize 等
2、资源加载,如 load、error 等
3、定时器,包括 setInterval、setTimeout 等
异步任务相关添加到任务队列 中(任务队列也称为消息队列)。
先执行执行栈中的同步任务。
异步任务放入任务队列中。
一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。
由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环( event loop)。
1 2 3 4 5 6 7 8 9 10 11 <body > <script > console .log (1 ) console .log (2 ) setTimeout (function ( ) { console .log (3 ) }, 0 ) console .log (4 ); </script > </body >
19.4 location
对象 1 2 3 4 5 6 7 location 的数据类型是对象,它拆分并保存了 URL 地址的各个组成部分 常用属性和方法: href 属性获取完整的 URL 地址,对其赋值时用于地址的跳转 search 属性获取地址中携带的参数,符号 ?后面部分 hash 属性获取地址中的啥希值,符号 # 后面部分 reload 方法用来刷新当前页面,传入参数 true 时表示强制刷新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <body > <form action ="" > <input type ="text" name ="username" > <input type ="password" name ="pwd" > <button > 提交</button > </form > <a href ="#/my" > 我的</a > <a href ="#/friend" > 关注</a > <a href ="#/download" > 下载</a > <button class ="reload" > 刷新</button > <script > const reload = document .querySelector ('.reload' ) reload.addEventListener ('click' , function ( ) { location.reload (true ) }) </script > </body >
5秒钟之后跳转到首页
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 <!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 > span { color : red; } </style > </head > <body > <a href ="http://www.baidu.cn" > 支付成功<span > 5</span > 秒钟之后跳转到首页</a > <script > const a = document .querySelector ('a' ) let num = 5 let timerId = setInterval (function ( ) { num-- a.innerHTML = `支付成功<span>${num} </span>秒钟之后跳转到首页` if (num === 0 ) { clearInterval (timerId) location.href = 'http://www.baidu.cn' } }, 1000 ) </script > </body > </html >
19.5 navigator
对象 navigator的数据类型是对象,该对象下记录了浏览器自身的相关信息
常用属性和方法:
通过 userAgent 检测浏览器的版本及平台
1 2 3 4 5 6 7 8 9 10 11 !(function ( ) { const userAgent = navigator.userAgent const android = userAgent.match (/(Android);?[\s\/]+([\d.]+)?/ ) const iphone = userAgent.match (/(iPhone\sOS)\s([\d_]+)/ ) if (android || iphone) { location.href = 'http://m.itcast.cn' } })()
19.6 histroy对象 history 的数据类型是对象,主要管理历史记录, 该对象与浏览器地址栏的操作相对应,如前进、后退、历史记录等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <body > <button > 后退</button > <button > 前进</button > <script > const back = document .querySelector ('button:first-child' ) const forward = back.nextElementSibling back.addEventListener ('click' , function ( ) { history.go (-1 ) }) forward.addEventListener ('click' , function ( ) { history.go (1 ) }) </script > </body >
20、本地存储 20.1 本地存储介绍 以前我们页面写的数据一刷新页面就没有了,是不是?
随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,HTML5规范提出了相关解决方案。
1、数据存储在用户浏览器中
2、设置、读取方便、甚至页面刷新不丢失数据
3、容量较大,sessionStorage和localStorage约 5M 左右
20.2 本地存储分类- localStorage 1 2 3 4 5 作用: 可以将数据永久存储在本地(用户的电脑), 除非手动删除,否则关闭页面也会存在 特性: 可以多窗口(页面)共享(同一浏览器可以共享) 以键值对的形式存储使用
语法:
1 2 3 4 5 6 7 存储数据: localStorage.setItem(key, value) 获取数据: localStorage.getItem(key) 删除数据 localStorage.removeItem(key)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <body > <script > localStorage .setItem ('uname' , '张三' ) console .log (localStorage .getItem ('uname' )) localStorage .setItem ('uname' , '张老师' ) localStorage .setItem ('age' , 18 ) console .log (localStorage .getItem ('age' )) </script > </body >
20.3 本地存储分类- sessionStorage 1 2 3 4 5 6 特性: 生命周期为关闭浏览器窗口 在同一个窗口(页面)下数据可以共享,另外一个页面无法获取到,默认返回的null 以键值对的形式存储使用 用法跟localStorage 基本相同
20.4 存储复杂数据类型 本地只能存储字符串,无法存储复杂数据类型.
解决: 需要将复杂数据类型转换成JSON字符串,在存储到本地
语法: JSON.stringify(复杂数据类型)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <body > <script > const obj = { uname : '张三' , age : 18 , gender : '女' } localStorage .setItem ('obj' , JSON .stringify (obj)) const str = localStorage .getItem ('obj' ) console .log (JSON .parse (str)) </script >
问题****: 因为本地存储里面取出来的是字符串,不是对象,无法直接使用
解决: 把取出来的字符串转换为对象
**语法:JSON.parse(JSON字符串)
20.5 数组中的map
方法 map 迭代数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <body > <script > const arr = ['red' , 'blue' , 'green' ] const newArr = arr.map (function (item, i ) { return item + 'hello' }) console .log (newArr) const arr1 = [10 , 20 , 30 ] const newArr1 = arr1.map (function (item ) { return item + 10 }) console .log (newArr1) </script > </body >
map 可以处理数据,并且返回新的数组
20.6 数组中join方法 join() 方法用于把数组中的所有元素转换一个字符串
1 2 3 4 5 6 7 8 <body > <script > const arr = ['red' , 'blue' , 'green' ] console .log (arr.join ('*' )) </script > </body >
参数:数组元素是通过参数里面指定的分隔符进行分隔的
21、正则表达式 正则表达式(Regular Expression
)是用于匹配字符串中字符组合的模式。在 JavaScript
中,正则表达式也是对象
通常用来查找、替换那些符合正则表达式的文本,许多语言都支持正则表达式。
正则表达式在 JavaScript
中的使用场景:
例如验证表单:用户名表单只能输入英文字母、数字或者下划线, 昵称输入框中可以输入中文(匹配 )
过滤掉页面内容中的一些敏感词(替换 ),或从字符串中获取我们想要的特定部分(提取 )等
21.1 语法
以/
开始,以/
结束
例如:
判断是否有符合规则的字符串
test() 方法 用来查看正则表达式与指定的字符串是否匹配
例如:
1 2 3 4 5 const str ='前端开发,前端工程师' const reg =/前端/ console .log (reg.test (str));
下面再来介绍另外一个方法:exec()
方法。在一个指定字符串中执行一个搜索匹配
例如:
1 2 3 4 5 const str ='前端开发,前端工程师' const reg =/前端/ console .log (reg.exec (str));
如果匹配成功,exec()
方法返回的是一个数组,否则返回null
.
21.2 元字符 普通字符
大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。 也就是说普通字符只能够匹配字符串中与它们相同的字符。
元字符 **(**特殊字符)
1 2 3 4 是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。 比如,规定用户只能输入英文26个英文字母,普通字符的话 abcdefghijklm….. 但是换成元字符写法: [a-z]
参考文档:
MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions
正则测试工具: http://tool.oschina.net/regex
1 2 3 4 5 为了方便记忆和学习,我们对众多的元字符进行了分类: 边界符(表示位置,开头和结尾,必须用什么开头,用什么结尾) 量词 (表示重复次数) 字符类 (比如 \d 表示 0~9)
21.2.1 边界符 正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符
如果 ^ 和 $ 在一起,表示必须是精确匹配
21.2.2 量词 量词用来 设定某个模式出现的次数
注意: 逗号左右两侧千万不要出现空格
21.2.3 字符类 (1)[ ] 匹配字符集合
后面的字符串只要包含 abc 中任意一个字符 ,都返回 true 。
(1)[ ] 里面加上 - 连字符
使用连字符 - 表示一个范围
1 2 3 4 5 比如: [a-z] 表示 a 到 z 26个英文字母都可以 [a-zA-Z] 表示大小写都可以 [0-9] 表示 0~9 的数字都可以
1 console .log (/^[a-z]$/ .test ('c' ));
(1)[ ] 里面加上 ^ 取反符号
1 2 3 4 比如: [^a-z] 匹配除了小写字母以外的字符 注意要写到中括号里面
用户名验证案例
需求:用户名要求用户英文字母,数字,下划线或者短横线组成,并且用户名长度为 6~16位
1 2 3 4 5 6 分析: (1):首先准备好这种正则表达式模式 /^[-a-zA-Z0-9_]{6,16}$/ (2):当表单失去焦点就开始验证. (3):如果符合正则规范, 则让后面的span标签添加 right 类. (4):如果不符合正则规范, 则让后面的span标签添加 wrong 类.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 <!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 > span { display : inline-block; width : 250px ; height : 30px ; vertical-align : middle; line-height : 30px ; padding-left : 15px ; } .error { color : red; background : url (./images/error1.png ) no-repeat left center; } .right { color : green; background : url (./images/right.png ) no-repeat left center; } </style > </head > <body > <input type ="text" > <span > </span > <script > const reg = /^[-a-zA-Z0-9_]{6,16}$/ const input = document .querySelector ('input' ) const span = input.nextElementSibling input.addEventListener ('blur' , function ( ) { if (reg.test (this .value )) { span.innerHTML = '输入正确' span.className = 'right' } else { span.innerHTML = '请输入6~16位的英文数字下划线' span.className = 'error' } }) </script > </body > </html >
预定义:指的是 某些常见模式的简写方式。
以数字开头,并且是4位数字
21.2.4 修饰符 修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等
语法:
1 2 3 i 是单词 ignore 的缩写,正则匹配时字母不区分大小写 g 是单词 global 的缩写,匹配所有满足正则表达式的结果
1 2 console .log (/a/i .test ('a' )) console .log (/a/i .test ('A' ))
1 2 3 console .log (/^java$/ .test ('java' )) console .log (/^java$/i .test ('JAVA' )) console .log (/^java$/i .test ('Java' ))
替换 replace 替换
语法
1 字符串.replace (/正则表达式/ ,'替换的文本' )
1 2 3 const str = 'java是一门编程语言, 学完JAVA工资很高' const re = str.replace(/java|JAVA/g, 'c#') console.log(re)
上面的正则表达式中,我们是添加了java
的大小写。
这里也可以使用i
这个修饰符来进行表示
1 2 const re = str.replace (/java/ig , 'c#' ) console .log (re)
敏感词过滤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <body > <textarea name ="" id ="" cols ="30" rows ="10" > </textarea > <button > 发布</button > <div > </div > <script > const tx = document .querySelector ('textarea' ) const btn = document .querySelector ('button' ) const div = document .querySelector ('div' ) btn.addEventListener ('click' , function ( ) { div.innerHTML = tx.value .replace (/激情|基情/g , '**' ) tx.value = '' }) </script > </body >