Web API(1~3)

Day1

课程安排

  • 第一天:DOM-获取元素(获取元素、修改属性)

  • 第二天:DOM-事件基础(注册事件、tab栏切换)

  • 第三天:DOM-事件进阶(事件对象、事件委托)

  • 第四天:DOM-节点操作(节点的增删改查)

  • 第五天:BOM-操作游览器(BOM、插件、本地存储)

  • 第六天:正则表达式(正则表达式、综合案例)

  • 第七天:实战(小兔鲜个人实战)

Web API基本认知

  • 变量声明:var(淘汰)、let、const(优先)

    • 复杂数据类型用const也可以改值,因为在栈里的地址没变

    • 建议数组和对象使用const声明

  • 作用和分类

    • 作用:JS操作HTML和游览器

    • 分类:DOM、BOM

  • 什么是DOM

    • 是文档对象模型,操作网页内容

  • DOM树

    • 将HTML文档以树状结构直观表现,称为文档树或DOM树

    • 作用:直观体现标签与标签间关系

  • DOM对象

    • 游览器根据HTML标签生成的JS对象

    • DOM核心思想:把网页内容当作对象处理

    • document对象:DOM提供的一个对象

      • 提供的属性和方法是用来访问和操作网页内容的

      • 网页所有内容都在document里

获取DOM对象

  • 根据CSS选择器来获取DOM元素

    • 选择匹配的第一个元素:document.querySelector('CSS选择器')

    • 选择匹配多个元素:document.querySelectorAll('CSS选择器')

      • 返回一个伪数组,有长度有索引,但没方法,要得对象需遍历

  • 其他获取DOM元素方法(了解即可)

    • 根据id获取一个元素:document.getElementById('nav')

    • 根据标签获取一类元素:document.getElementsByTagName('div')

    • 根据类名获取元素:document.getElementsByClassName('w')

操作元素内容

  • 目标:能改元素的文本更换内容

  • 对象.innerText属性

    • 将文本内容添加/更新到任意标签位置,显示纯文本,不解析标签

  • 对象.innerHTML属性

    • 将文本内容添加/更新到任意标签位置,会解析标签,多标签建议使用模板字符

  • 练习--年会抽奖

    • //声明数组

    • const personArr = ['小明','小红','小刚']

    • //随机数 数组的下标

    • const random=Math.floor(Math.random()*personArr.length)

    • //获得one元素(一等奖)

    • const one=document.querySelector('#one')

    • //把名字给one

    • one.innerHTML=personArr[random]

    • //删除这个名字

    • personArr.splice(random,1)

操作元素属性

  • 操作元素常用属性

    • 对象.属性=值

    • 练习--页面刷新,图片随机更换

      • funtion getRandom(N,M) {

        • return Math.floor(Math.random()*(M-N+1))+N

      • }

      • //获取图片对象

      • const img=document.querySelector('img')

      • //随机得到序号

      • const random=getRandom(1,6)

      • //更换路径

      • img.src=`./images/${random}.webp`

  • 操作元素样式属性

    • 通过style属性操作CSS:对象.style.样式属性=值(多组单词小驼峰命名)

      • 练习--页面刷新,页面随机更换背景图片

        • <head>

          • <style>

            • body {

              • background: url(./images/desktop_1.jpg) no-respeat top center cover;

            • }

          • </style>

        • </head>

        • <body>

          • <script>

            • funtion getRandom(N,M) {

              • return Math.floor(Math.random()*(M-N+1))+N

            • }

            • const random=getRandom(1,10)

            • document.body.style.backgroundImage=`url(./images/desktop_${random}.jpg)`

          • </script>

        • </body>

    • 操作类名(className)操作CSS

      • 元素.className='CSS类名'

      • className是新值换旧值,若要添加一个类,需保留之前的类名

    • 通过classList操作类控制CSS

      • 为解决className覆盖以前类名,可用classList方式追加和删除类名

      • 追加一个类:元素.classList.add('类名')

      • 删除一个类:元素.classList.remove('类名')

      • 切换一个类:元素.classList.toggle('类名')

      • 练习--轮播图随机版

        • const sliderData=[{...},{...},{...}]//初始数据

        • //需要一个随机数

        • const random=parseInt(Math.random()*sliderData.length)

        • //获取图片

        • const img=document.querySelector('.slider-wrapper img')

        • //修改图片路径 对象.url

        • img.src=sliderData[random].url

        • //修改文字内容

        • const p=document.querySelector('.slider-wrapper img') //获取

        • p.innerHTML=sliderData[random].title //修改

        • // 修改背景颜色

        • const footer=document.querySelector('.slider-footer')

        • footer.style.backgroundColer=sliderData[random].color

        • //小圆点

        • const li=document.querySelector(`.slider-indicator li:nth-child(${random+1})`)

        • //让当前li添加active类(实现高亮)

        • li.classList.add('active')

  • 操作表单元素属性

    • 获取:DOM对象.属性名

    • 设置:DOM对象.属性名=新值

    • 表单属性添加、移除效果,一律用布尔值表示

      • 比如:disabled、checked、selected

      • <input type="checked" name="" id="">

      • <button>点击</button>

      • <script>

        • const ipt=document.querySelector('input')

        • ipt.checked=true //选中

        • const button=document.querySelector('button')

        • button.disabled=true //禁用

      • </script>

  • 自定义属性

    • 标准属性、自定义属性

    • HTML5出了专门的data-自定义属性

    • 标签一律以data-开头,在DOM对象上一律以dataset对象方式获取

定时器-间歇函数

  • 定时器函数介绍

    • 开启定时器:setInterval(函数,间隔时间)(间隔时间单位是毫秒)

      • 函数名字不需要加括号

      • 定时器返回的是一个id数字,独一无二

    • 关闭定时器:

      • let 变量名=setInterval(函数,间隔时间)

      • clearInterval(变量名)

    • 练习--阅读用户协议

      • <body>

        • <textarea ...>

          • 文本

        • </textarea>

        • <br>

        • <button class="btn" disabled>我已阅(5)</button>

        • <script>

          • const btn=document.querySelector('.btn')

          • let i = 5

          • let n=setInterval(funtion() {

            • i--

            • btn.innerHTML=`我已阅(${i})`

            • if(i===0) {

              • clearInterval(n)

              • btn.disabled=false //开按钮

              • btn.innerHTML='同意'

            • }

          • },1000)

        • </script>

      • </body>

  • 定时器函数基本使用

综合案例--轮播图定时器版

  • 需求:每隔一秒切换图片

  • //初始化 略

  • //获取元素

  • const img=document.querySelector('.slider-wrapper img')

  • const p=document.querySelector('.slider-footer p')

  • let i=0

  • //开定时器

  • setInterval(funtion(){

    • i++

    • //最后一张之后的无缝衔接

    • if(i>=sliderData.length) {

      • i=0

    • }

    • //更换图片路径

    • img.src=sliderData[i].url

    • //把字写到p里

    • p.innerHTML=sliderData[i].title

    • //小圆点

    • //先删以前的active

    • document.querySelector('.slider-indicator .active').classList.remove('active')

    • //只让当前li添加active

    • document.querySelector(`.slider-indicator li:nth-child(${i+1})`).classList.add('active')

  • },1000)

Day2

事件监听(绑定)

  • 事件监听

    • 元素对象.addEventListener('事件类型',要执行的函数)

    • 三要素:事件源、事件类型、事件调用函数

    • 练习

      • <button>点击</button>

      • <script>

        • const btn=document.querySelector('button')

        • btn.addEventListener('click',funtion() {

          • alert('你好')

        • })

      • </script>

    • 练习--关闭广告

      • <style>

        • .box1 {... cursor: pointer} //广告的叉掉标识

      • </style>

      • <script>

        • //获取事件源

        • const box1=document.querySelector('.box1')

        • //关闭的是大盒子

        • const box=document.querySelector('.box')

        • //事件监听

        • box1.addEventListerner('click',funtion() {

          • box.style.display='none'

        • })

      • </script>

    • 练习--随机点名案例

      • <script>

        • //数据数组

        • const arr=['马超','黄忠','赵云','关羽','张飞']

        • //1.开始按钮转换

        • const qs=document.querySelector('.qs')

        • let timeId=0 //定时器全局变量

        • let random=0 // 随机号要全局变量

        • //1.1获取开始按钮对象

        • const start=document.querySelector('.start')

        • //1.2添加点击事件

        • start.addEventListener('click',funtion() {

          • timerId.setInterval(funtion() {

            • //随机数

            • random=parseInt(Math.random()*arr.length)

            • qs.InnerHTML=arr[random]

          • },35)

          • //如果数组里只有一个值,不需抽取,让两个按钮禁用

          • if(arr.length===1) {

            • start.disabled=end.disabled=true

          • }

        • })

        • //2.关闭按钮模块

        • const end=document.querySelector('.end')

        • end.addEventListener('click',funtion() {

          • clearInterval(timeId)

          • //结束一轮就删掉当前抽到的

          • arr.splice(random,1)

        • })

      • </script>

  • 拓展阅读-事件监听版本

    • DOM L0:事件源.on事件=function() {}

    • DOM L2:事件源.addEventListener(事件,事件处理函数)

    • 区别:on方式会被覆盖,addEventListener方式可绑定多次,推荐

事件类型

  • 鼠标事件(鼠标触发)

    • click鼠标点击

    • mouseenter鼠标经过

    • mouseleave鼠标离开

    • 练习--轮播图点击切换

      • <script>

        • //获取元素

        • const img=document.querySelcetor('.slider-wrapper img')

        • const p=document.querySelector('.slider-footer p')

        • const footer=document.querySelector('.slider-footer')

        • //右侧按钮业务

        • //1.1获取右侧按钮

        • const next=document.querySelector('.next')

        • let i=0 //信号量,控制播放图片张数

        • //1.2注册点击事件

        • next.addEventListener('click',funtion() {

          • i++

          • //1.6判断条件,实现衔接

          • i= i>=data.length? 0 : i

          • //1.3得到对应对象

          • //调用函数

          • toggle()

        • })

        • //左侧按钮业务

        • //2.1获取左侧按钮

        • const prev=document.querySelector('.prev')

        • //2.2注册点击事件

        • prev.addEventListener('click',funtion() {

          • i--

          • //2.6判断条件,实现衔接

          • i= i<0? data.length-1 : i

          • //2.3得到对应对象

          • //调用函数

          • toggle()

          • //声明一个渲染函数作为复用

          • function toggle() {

            • //1.4渲染对应数量

            • img.src=data[i].url

            • p.innerHTML=data[i].title

            • footer.style.background=data[i].color

            • //1.5更换小圆点 先移除,再添加

            • document.querySelector(`.slider-indicator .active`).classList.remove('active')

            • document.querySelector(`.slider-indicator li:nth-child(${i+1})`).classList.add('active')

          • }

        • })

        • //3.自动播放模块

        • let timeId=setInterval(function(){

          • //利用JS自动调用点击事件

          • next.click()

        • },1000)

        • //4.鼠标经过大盒子停止定时器

        • const slider=document.querySqlqctor('.slider')

        • //注册事件

        • slider.addEventListener('mouseenter',function() {

          • //停止定时器

          • clearInterval(timeId)

        • })

        • //5.鼠标离开大盒子开启定时器

        • //注册事件

        • slider.addEventListener('mouseleave',function() {

          • //停止定时器 (好习惯,先关再开)

          • clearInterval(timeId)

          • //开启定时器

          • timeId=setInterval(function(){

            • //利用JS自动调用点击事件

            • next.click()

          • },1000)

        • })

      • </script>

  • 焦点事件(表单获得光标)

    • focus获得焦点

    • blur失去焦点

    • <input type="text">

    • <script>

      • const input=document.querySelector('input')

      • input.addEventListener('focus',function() {

        • console.log('有焦点触发')

      • })

      • input.addEventListener('blur',function() {

        • console.log('无焦点触发')

      • })

    • </script>

    • 练习--小米搜索框

      • <div class="mi">

        • <input type="search" placeholder="小米笔记本">

        • <ul class="result-list">

          • <li><a href="#">全部商品</li>

          • <li><a href="#">小米笔记本</li>

          • <li><a href="#">小米蓝牙</li>

          • <li><a href="#">小米手机</li>

        • <ul>

      • </div>

      • <script>

        • const input=document.querySelector('[type-search]')//属性选择器

        • input.addEvenListener('focus',function(){

          • ul.style.display='block'

          • imput.classList.add('search')

        • })

        • input.addEvenListener('blur',function(){

          • ul.style.display='none'

          • imput.classList.remove('search')

        • })

      • </script>

  • 键盘事件(键盘触发)

    • Keydown键盘按下触发

    • Keyup键盘抬起触发

  • 文本事件(表单输入触发)

    • input用户输入事件

    • 练习--评论字数统计

      • <style>

        • input {

          • width: 200px;

          • transition: all .3s;

        • }

        • input:focus { //focus伪类选择器,获得焦点

          • width: 300px;

        • }

      • </style>

      • <script>

        • const tx=document.querySelector('#tx')

        • const total=document.querySelector('.total')

        • //文本获得焦点,就让total显示

        • tx.addEventListener('focus',function() {

          • total.style.opacity=1

        • })

        • //文本失去焦点,就让total隐藏

        • tx.addEventListener('blur',function() {

          • total.style.opacity=0

        • })

        • //检测用户输入

        • tx.addEventListener('input',function() {

          • total.innerHTML=`${tx.value.length}/200字`

        • })

      • </script>

事件对象

  • 获取事件对象:元素.addEventListener('click',function(e) {})

  • 事件对象常用属性

    • type

      • 获取当前的事件类型

    • clientX/clientY

      • 获取光标相对于游览器可见窗口左上角的位置

    • offsetX/offsetY

      • 获取光标相对于当前DOM元素左上角的位置

    • key

      • 用户按下的键盘键的值

      • 现在不提倡使用keyCode

      • 练习--评论回车发布

        • //接上一例

        • const item=document.querySelector('.item')

        • const text=document.querySelector('.text')

        • //按下回车发布评论

        • 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字'

          • }

        • })

环境对象

  • 特殊变量this,代表当前函数运行时所处环境

  • 每个函数都有this,普通函数的this指向window

  • 函数调用方式不同,this指向对象不同。谁调用,this指谁(粗略规则)

回调函数

  • 将函数A作为参数传给函数B时,称函数A为回调函数

  • 回头调用

  • 使用匿名函数作为回调函数较常见

综合案例--Tab栏切换

  • const as=document.querySelectorAll('.tab-nav a')

  • for(let i=0;i<as.length;i++) {

    • //要给几个链接绑定鼠标经过事件

    • as[i].addEventListener('mouseenter',function(){

      • //排他思想

      • document.querySelector('.tab-nav .active').classList.remove('active')

      • this.classList.add('active')

      • //下部大盒子一一对应

      • document.querySelector('.tab-content .active').classList.remove('active')

      • document.querySelector('.tab-content .item:nth-child(${i+1})').classList.add('active')

    • })

  • }

Day3

案例--全选文本框

  • <script>

    • //1.获取大复选框

    • const checkAll=document.querySelector('#checkAll')

    • //2.获取小复选框

    • const cks=document.querySelectorAll('.ck')

    • //3.点击大复选框,注册事件

    • checkAll.addEventListener('click',function() {

      • //得到当前大复选框选中状态

      • //console.log(checkAll.checked) //得到true或false

      • 4.遍历所有小复选框 让小的checked=大的checked

      • for(let i=0; i<cks.length; i++) {

        • cks.[i].checked=checkAll.checked

      • }

    • })

    • //5.小复选框控制大

    • for(let i=0;i<cks.length;i++) {

      • //5.1给所以小添加点击事件

      • cks[i].addEventListener('click',function() {

        • //判断选中小的个数是不是等于总的小个数

        • checkAll.checked= document.querySelectorAll('.ck:checked').length==cks.length

      • })

    • }

  • </script>

事件流

  • 事件流与两个阶段说明

    • 是事件完整执行过程中的流动路径

    • 捕获阶段(父到子)

    • 冒泡阶段(子到父)(实际工作冒泡为主)

  • 事件捕获

    • 概念:从DOM元素的根元素开始去执行对应的时间(从外到里)

    • DOM.addEventListener(事件类型,事件处理函数,是否使用捕获机制)

  • 事件冒泡

    • 概念:一个元素触发事件后,依次向上调用所以父级元素的同名事件

    • 默认存在。第三个参数是false,或默认都是冒泡

  • 阻止冒泡

    • 问题:容易影响父级元素

    • 需求:把事件限制在当前元素内

    • 前提:阻止冒泡需拿到事件对象

    • 语法:事件对象.stopPropagation()

      • 此方法可以阻断事件流动传播,不光在冒泡,捕获阶段也有效

    • 阻止默认行为:e.preventDefault()

  • 解绑事件

    • on事件方法,直接用null覆盖

      • //绑定事件

      • btn.onclick=function() {

        • alert('点击了')

      • }

      • //解绑事件

      • btn.onclick=null

    • addEventListener方式必须用:

      • removeEventListener(事件类型,事件处理函数[,获取捕获或者冒泡阶段])

      • function fn() {

        • alert('点击了')

      • }

      • //绑定事件

      • btn.addEventListener('click',fn)

      • //解绑事件

      • btn.removeEventListener('click',fn)

    • 鼠标经过事件的区别

      • mouseover和mouseout会有冒泡效果

      • mouseenter和mouseleave没有冒泡效果(推荐)

事件委托

  • 是利用事件流的特征解决一些开发需求的知识技巧

  • 优点:减少注册次数,提高程序性能

  • 原理:利用事件冒泡特点

    • 给父元素注册事件,触发子元素时会冒泡到父元素身上,从而触发父元素

  • 实现:事件对象.target.tagName可获得真正触发事件的元素

  • 练习--tab栏切换改造

其他事件

  • 页面加载事件

    • load事件

      • 有时需等页面全处理完再做事情。老代码把script写在head,直接找dom元素找不到

      • 监听页面所有资源加载完毕

        • window.addEventListener('load',function(){...}) //给window添加load

    • DOMContentLoaded

      • 当初始HTML加载解析完后,DOMContentLoaded触发,无需等完全加载

      • 监听页面DOM加载完毕

        • document.addEventListener('DOMContentLoaded',function(){...})

  • 元素滚动事件

    • 滚动条滚动时触发

    • 给window或document添加scroll事件

    • 获取位置:scrollLeft和scrollTop,可读写,数字型,不带单位

    • 滚动到哪出现或消失

      • <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' //opacity有淡出淡入效果

          • }

        • })

      • </script>

    • 点击返回页面顶部

      • const backTop=document.querySelector('#backTop')

      • backTop.addEventListener('click',function() {

        • document.documentElement.scrollTop=0

      • })

    • 滚动到指定坐标

      • 元素.scrollTo(x,y)

  • 页面尺寸事件

    • 会在窗口尺寸改变时触发事件

      • window.addEventListener('resize',function() {...})

    • 检测屏幕宽度

      • window.addEventListener('resize',function() {

        • let w=document.documentElement.clientWidth

        • console.log(w)

      • })

      • 获得宽高:clientWidth、clientHeight。(不含边框、margin、滚动条)

元素尺寸与位置

  • 通过JS得到元素在页面中的位置

  • 获得宽高:offsetWidth、offsetHeight,包含元素padding、border

    • 结果是数值

    • 注:获取的是可视的,若隐藏,结果为0

  • 获取位置:offsetLeft、offsetTop。(只读属性)

    • 获取元素距离自己定位父级元素的左、上距离

    • 大于某盒子的某位置就隐藏或消失

      • elevator.style.opacity= n>=entry.offsetTop?1:0

    • 练习--模仿京东固定导航栏

      • <script>

        • const sk=document.querySelector('.sk')

        • const header=document.querySelector('.header')

        • window.addEventListener('scroll',function() {

          • const n=document.documentElement.scrollTop

          • header.style.top=n>=sk.offsetTop?0:'-80px'

        • })

      • </script>

    • 练习--实现bilibili点击小滑块移动效果

      • .line {

        • position: absolute;

        • ...

        • transition: all .3s; 过渡效果

      • }

      • <script>

        • //获取父元素,添加事件委托

        • const list=document.querySelector('.tabs-list')

        • const line=document.querySelector('.line')

        • //给a注册事件

        • list.addEventListener('click',function(e) {

          • //判断点击的是a

          • if(e.target.tagName==='A') {

            • //得到当前链接offsetLeft

            • //让line盒子进行移动

            • line.style.transform=`translateX(${e.target.offsetLeft}px)`

          • }

        • })

      • </script>

  • 获取位置2:element.getBoundingClientRect()

    • 返回元素的大小及其相对于视口的位置

综合案例--电梯导航

  • //以下在CSS里写

  • //让页面丝滑滚动

  • html {

    • scroll-behavior: smooth;

  • }

  • //以下在script里写

  • //第一大模块,页面滑动可以显示和隐藏

  • (function() {...})();

  • //第二第三放在另外一个执行函数里(防止污染)

  • (function() {

    • //2.点击页面可以滑动

    • const list=document.querySelector('.xtx-elevator-list')

    • list.addEventListener('click',function(e) {

      • if(e.target.tagName==='A' && e.target.dataset.name) {

        • //排他思想

        • const old=document.querySelector('.xtx-elevator-list .active')

        • if(old) old.classList.remove('active')

        • e.target.classList.add('active')

        • //获取对应大盒子的offsetTop

        • const top=document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop

        • //让页面滚动到对应位置

        • document.documentElement.scrollTop=top

      • }

    • })

    • //3.页面滑动,可以根据大盒子选小盒子添加active类

    • window.addEventListener('scroll',function() {

      • //3.1 先移除类

      • const old=document.querySelector('.xtx-elevator-list .active')

      • if(old) old.classList.remove('active')

      • //3.2判断页面当前滑动位置,选择小盒子

      • //获取四个大盒子

      • const news=document.querySelector('.xtx_goods_new')

      • const popular=document.querySelector('.xtx_goods_new')

      • const brand=document.querySelector('.xtx_goods_new')

      • const topic=document.querySelector('.xtx_goods_new')

      • const n=document.documentElement.scrollTop

      • if(n>=news.offsetTop&&n<popular.offsetTop) {

        • document.querySelector('[data-name=new]').classList.add('active')

      • }else if(n>=popular.offsetTop&&n<brand.offsetTop) {

        • document.querySelector('[data-name=popular]').classList.add('active')

      • }else if(n>=brand.offsetTop&&n<topic.offsetTop) {

        • document.querySelector('[data-name=brand]').classList.add('active')

      • }else if(n>=topic.offsetTop) {

        • document.querySelector('[data-name=topic]').classList.add('active')

      • }

  • })

  • })();

属性选择器

  • [ ]

自定义属性集合

  • dataset

  • dataset.name


Web API(1~3)
http://localhost:8090//archives/apis
作者
江敏婕
发布于
2024年10月21日
许可协议