目录
DOM-网页特效
手风琴案例
<script>
// 1. li 默认有个宽度是 240像素
// 2. 当我们鼠标经过, 当前的小li 宽度变大 800px 其余的小li 变为 100px
// 3. 鼠标离开事件, 所有的小li 都要复原 宽度为 240px
// (1) 获取元素
let lis = document.querySelector('li')
// let lis = document.querySelectorAll('li')
// (2) 绑定鼠标经过和离开事件
for (let i = 0; i < lis.length; i++) {
lis[i].addEventListener('mouseenter', function () {
for (let j = 0; j < lis.length; j++) {
lis[j].style.width = '100px'
}
this.style.width = '800px'
})
lis[i].addEventListener('mouseleave', function () {
for (let j = 0; j < lis.length; j++) {
lis[j].style.width = '240px'
}
})
}
</script>
加载事件
- load:所有资源加载完load
- DOMContentLoaded:HTML完全加载和解析后触发
三大家族
- scroll家族
- 获取元素内容的总大小
- 获取元素向左向上滚出去看不见的距离 可读写属性
- offset家族
- 获取元素自身大小:包括自身设置的宽高、padding、border
- 获取元素距离定位父级的左和上距离 只读属性
- client家族
- 获取元素可见区域的大小
- 获取元素左、上边距离 只读属性
<script>
// scrollWidth scrollHeight 内容 宽高 (了解)
let div = document.querySelector('div')
console.log(div.scrollWidth) // 150 不带单位
console.log(div.scrollHeight) // 336 不带单位
console.log('----------------------------')
// offset 盒子元素的大小 = 盒子本身的宽度和高度 + padding + border
console.log(div.offsetWidth) // 150 不带单位
console.log(div.offsetHeight) // 150 不带单位
// console.log(div.offsetTop) //
// console.log(div.offsetLeft)
// client 当前可视区域 不包含滚动条 边框等等
console.log('----------------------------')
console.log(div.clientWidth)
console.log(div.clientHeight)
console.log(div.clientTop) // 边框的宽度 了解 呵呵
console.log(div.clientLeft)
// 2. 被卷去的头部和左侧
// div.addEventListener('scroll', function () {
// console.log(document.querySelector('div').scrollTop)
// })
</script>
返回顶部
<script>
// 0 获取元素
let backtop = document.querySelector('.backtop')
// 一. 页面滚动事件
window.addEventListener('scroll', function () {
// 2. 页面检测滚动的距离
// console.log(document.documentElement.scrollTop)
let num = document.documentElement.scrollTop
// 3. 进行判断显示和隐藏
if (num >= 500) {
//显示那个元素
backtop.style.display = 'block'
} else {
// 否则隐藏元素
backtop.style.display = 'none'
}
})
// 二、点击链接返回顶部 backtop.children[1]
backtop.children[1].addEventListener('click', function () {
// 返回顶部
// scrollTop 可读写
document.documentElement.scrollTop = 0
})
</script>
轮播图
<script>
// 轮播图开始啦
// 需求①:小图标鼠标经过事件
// 鼠标经过小图片,当前高亮,其余兄弟变淡 添加类
let lis = document.querySelectorAll('.indicator li')
let piclis = document.querySelectorAll('.slides ul li')
let text = document.querySelector('.extra h3')
let next = document.querySelector('.next')
let prev = document.querySelector('.prev')
let main = document.querySelector('.main')
// 给多个小li绑定事件
for (let i = 0; i < lis.length; i++) {
lis[i].addEventListener('mouseenter', function () {
// 选出唯一的那个active ,删除类
document.querySelector('.indicator .active').classList.remove('active')
// 鼠标经过谁,谁加上active 这个类
this.classList.add('active')
// 需求② :大图片跟随变化 一定要放到鼠标经过事件里面
// 对应的大图片跟着显示,如果想要过渡效果,可以使用opacity效果,可以利用CSS淡入 淡出的效果,还是添加类
// 选出唯一的那个active ,删除类
document.querySelector('.slides ul .active').classList.remove('active')
// 对应序号的那个 li,谁加上active 这个类
piclis[i].classList.add('active')
text.innerHTML = `第${i + 1}张图的描述信息`
// 需求④:解决一个BUG
// 点击右侧按钮可以实现播放下一张,但是鼠标经过前面的,播放就会乱序
// 解决方案: 让变化量 index 重新赋值为 当前鼠标经过的索引号
// 鼠标经过了那个小li 他的索引号就是 i
// 右侧按钮是通过 index 来了控制播放的
index = i
})
}
// 需求③:右侧按钮播放效果
// 点击右侧按钮,可以自动播放下一张图片
// 需要一个变化量 index 不断自增
// 然后播放下一张图片
// 如果到了最后一张,必须要还原为第1张图片
// 教你一招: 索引号 = 索引号 % 数组长度 (放到播放前面)
let index = 0 // 全局变量 信号量 控制器 为了给 右侧按钮和左侧按钮同时使用
next.addEventListener('click', function () {
index++
// 选出 index 小图片 做操作
// console.log(index)
// if (index === lis.length) {
// index = 0
// }
index = index % lis.length
common()
})
// 需求⑤:左侧按钮播放效果
// 点击左侧按钮,可以自动播放上一张图片
// 需要一个变化量 index 不断自减
// 然后播放上一张图片
// 如果到了第一张,必须要从最后一张播放
// 教你一招: 索引号 = (数组长度 + 索引号) % 数组长度
prev.addEventListener('click', function () {
index--
// 选出 index 小图片 做操作
// console.log(index)
if (index < 0) {
index = lis.length - 1
}
// index = (lis.length + index) % lis.length
common()
})
// 需求⑥:
// 因为左侧按钮和右侧按钮里面有大量相同的操作,可以抽取封装一个函数 common
function common() {
document.querySelector('.indicator .active').classList.remove('active')
lis[index].classList.add('active')
// 选出 index 大图片 做操作
document.querySelector('.slides ul .active').classList.remove('active')
piclis[index].classList.add('active')
text.innerHTML = `第${index + 1}张图的描述信息`
}
// 需求⑦:开启定时器
// 其实定时器自动播放,就相当于点击了右侧按钮,此时只需要, next.click()
let timer = setInterval(function () {
// 自动调用右侧按钮的点击事件
next.click()
}, 1000)
// 需求⑧:
// 鼠标经过停止定时器 (清除定时器)
main.addEventListener('mouseenter', function () {
clearInterval(timer)
})
// 鼠标离开开启定时器 (开启定时器)
main.addEventListener('mouseleave', function () {
timer = setInterval(function () {
// 自动调用右侧按钮的点击事件
next.click()
}, 1000)
})
Window对象
BOM是浏览器对象模型
window 包含了 navigator\location\document\history\screen 5个属性
延迟函数
5秒广告
<script>
let img = document.querySelector('img')
setTimeout(function () {
img.style.display = 'none'
}, 5000)
</script>
递归函数
<script>
// 利用递归函数 模拟了 setinterval
let div = document.querySelector('div')
function fn() {
div.innerHTML = new Date().toLocaleString()
setTimeout(fn, 1000)
}
fn()
</script>
JS执行机制
事件循环(event loop)
JS是单线程
同步
前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。
同步任务都是在主线程上执行的,形成一个执行栈
异步
在做一件事时,因为这件事情会花费很长时间,在做这件事情的同时,还可以处理其他事情。
js的异步是通过回调函数实现的,一般而言异步任务有以下三种类型:
- 普通事件,如click、resizeset
- 资源加载,如load、error
- 定时器,包括setInterval、setTimeoutset
location对象
- href 属性获取完整的 URL 地址,对其赋值时用于地址的跳 转
- search 属性获取地址中携带的参数,符号 ?后面 部分
- hash 属性获取地址中的啥希值,符号 # 后面部分
- 后期 vue 路由的铺垫,经常用于不刷新页面,显示不同页面,比如 网易云音乐
- reload 方法用来刷新当前页面,传入参数 true 时表示强制刷新
navigator对象
// 检测 userAgent(浏览器信息)
!(function () {
const userAgent = navigator.userAgent
// 验证是否为Android或iPhone
const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/)
const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/)
// 如果是Android或iPhone,则跳转至移动站点
if (android || iphone) {
location.href = 'http://m.itcast.cn'
}
})()
history对象
history 的数据类型是对象,该对象与浏览器地址栏的操作相对应,如前进、后退、历史记录 等
swiper插件
https://www.swiper.com.cn/
本地存储
localStorage
- 生命周期 永久生效,除非手动删除 否则关闭页面也会存在
- 可以多窗口(页面)共享(同一浏览器可以共享)
- 以键值对的形式存储使用
存储数据
localStorage.setItem(key,value)
获取数据
localStorage.getItem(key)
删除数据
localStorage.removeItem(key)
存储复杂数据类型存储
本地只能存储字符串 无法存储复杂数据类型 需要将复杂数据类型转换成 JSON 字符串 再存储到本地
.JSON.stringify(复杂数据类型)
将 复杂数据转换成 JSON 字符串 存储 本地存储中
JSON.parse(JSON 字符串)
将 JSON 字符串转换成 对象 取出 时候使用
let obj = {
uname: '刘德华',
age: 17,
address: '黑马程序员'
}
localStorage.setItem('obj', JSON.stringify(obj))
console.log(JSON.parse(localStorage.getItem('obj')))
sessionStorage (了解)
- 生命周期为关闭浏览器窗口
- 在同一个窗口 页面 下数据可以共享
- 以 键值对的形式存储 使用
- 用法跟 localStorage 基本相同
正则表达式
<script>
// 定义正则表达式 reg 里面存的是对象
let reg = /前端/
// 2. 检测是否匹配 test (重点)
let str = '我们大家都在学前端'
console.log(reg.test(str))
// 3. 检索 exec()
console.log(reg.exec(str)) // 返回的是数组
</script>
元字符
- 边界符(表示位置,开头和结尾,必须用什么开头,用什么结尾)
- 量词 (表示重复次数)
- 字符类 (比如 d 表示 0~9)
边界符
<script>
// console.log(/哈/.test('哈哈'))
// console.log(/哈/.test('二哈'))
// ^ 开头
console.log(/^哈/.test('二哈')) // false
console.log(/^哈/.test('我开心的哈哈大笑')) // false
console.log(/^哈$/.test('我开心的哈哈大笑')) // false
console.log(/^哈$/.test('哈哈')) // false
console.log(/^哈$/.test('哈')) // true 精确匹配
</script>
量词
<script>
// console.log(/a/.test('a'))
// // * 量词 n >= 0
// console.log(/a*/.test(''))
// console.log(/a*/.test('a'))
// console.log(/a*/.test('aa'))
// console.log(/a*/.test('aaaaaaaa'))
// console.log(/a*/.test('b'))
// console.log('--------------------------')
// // + 量词 n >= 1
// console.log(/a+/.test(''))
// console.log(/a+/.test('a'))
// console.log(/a+/.test('aa'))
// console.log(/a+/.test('aaaaaaaa'))
// console.log(/a+/.test('b'))
// console.log('--------------------------')
// // ? 出现 0 || 1
// console.log(/^a?$/.test(''))
// console.log(/^a?$/.test('a'))
// console.log(/^a?$/.test('aa'))
// {n} 只能出现 n次 符号之间不要加空格
console.log(/^a{3}$/.test('aa'))
console.log(/^a{3}$/.test('aaa'))
console.log(/^a{3}$/.test('aaaa'))
// {n,} >= n
console.log(/^a{3,}$/.test('aa'))
console.log(/^a{3,}$/.test('aaa'))
console.log(/^a{3,}$/.test('aaaa'))
console.log('--------------------------')
// {n,m} >= n <= m
console.log(/^a{3,6}$/.test('aa'))
console.log(/^a{3,6}$/.test('aaa'))
console.log(/^a{3,6}$/.test('aaaa'))
console.log(/^a{3,6}$/.test('aaaaa'))
console.log(/^a{3,6}$/.test('aaaaaaaa'))
</script>
字符类
<script>
// console.log(/abc/.test('abc'))
// console.log(/abc/.test('ab'))
// 字符类 []
// console.log(/[abc]/.test('abc'))
// console.log(/[abc]/.test(''))
// console.log(/[abc]/.test('andy'))
// console.log(/[abc]/.test('baby'))
// console.log(/[abc]/.test('cry'))
// console.log(/[abc]/.test('die'))
// 字符类 [-] 连字符
console.log(/^[abc]$/.test('abc'))
console.log(/^[abc]$/.test('a'))
console.log(/^[abc]$/.test('b'))
console.log(/^[abc]$/.test('c'))
console.log(/^[abc]$/.test('cc'))
// 26个英文字母选其中的一个
console.log(/^[a-zA-Z]$/.test('d'))
console.log(/^[a-zA-Z]$/.test('D'))
console.log(/^[a-zA-Z]$/.test('DD'))
console.log(/^[a-zA-Z0-9]$/.test('6'))
console.log(/^[a-zA-Z0-9-_]$/.test('6'))
console.log(/^abc+$/.test('cc'))
</script>
^在[]内表示取反 .代表除换行符之外的任何字符