因为之前学过一点 就当作一个学习记录
JavaScript
是实现人机交互效果
- 网络特效
- 数据交互
- 表单验证
- 服务器编程
JS的组成
- 基本语法ECMAscript
- WebAPIS DOM(页面文档对象) BOM(浏览器对象模型)
输入输出语法
- document.write() 在页面显示
- alert() 弹出警示框
- prompt() 弹出询问框
- console.log() 在打印台上打印
字面量是指在计算机中描述事/物
变量
计算机存储数据的容器,可以让计算机变得有记忆
- 声明变量:创建变量let/const+变量名
- eg let a = 10
- 更新变量:变量赋值后还可以通过简单地给她一个不同的值来更新
- 多行变量
数组
可以存放多个变量 let arr = []
加号可以使字符串变成数据型
eg: let a = +prompt('‘)
添加元素: push() unshift() 一个是在末尾添加 一个是在开头添加 都是可以删除好几个元素
删除元素:pop() 删除最后一个元素 shift() 删除最前的一个元素 splice(index,length) 删除指定位置的元素
排序sort:
默认是升序排序
降序排序:
arr.sort(function(a,b){
return b-a}
形参和实参
形参等于上述例子的a,b 是形式上的参数
实参就是实际的参数值 即对函数的赋值 eg add(10,2) 10和2就是实参
函数返回值
return
return和break的区别 return是结束函数 break是结束循环
作用域
可用性的代码范围就是作用域
立即执行函数 在函数function前后加括号
例子一 时间转换(将秒数转换成xxhxxminxxs形式)
小时H = parseInt(sum/60/60%24)\
分钟M = parseInt(sum/60%60)
秒数S = parseInt(sum%60)
逻辑中断
&& 与 || 或 (3>5)&&0 如果前面为false后面的语句就不执行
对象object
是一种数据类型 一种无序的数据集合,数组是有序的数据集合,其实就相当于java中的字典
成对出现,包括属性名和属性值
有增删改查四个基本操作 delete是删除指令 没有查询到时会返回NaN
遍历采用for(let k in obj){console.log(k) console.log(obj[k])
内置对象
js内部提供的对象包括各种属性的方法和开发者调用,最常用的就是Math(ceil/Pi/floor/max/min/round)
生成随机数:Math.floor(Math.random()*(M-N+1))+N
新生成的空间存放在栈里面 和new比较像吧
一个抽奖的练习:
<!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>
<div class="wrapper">
<strong>抽奖</strong>
<h1>一等奖:<span id="one">???</span></h1>
<h3>二等奖:<span id="two">???</span></h3>
<h5>三等奖:<span id="three">???</span></h5>
</div>
<script>
const arr = ['周杰伦', '刘德华', '周星驰', 'pink', '张学友']
const random = Math.floor(Math.random() * arr.length)
const one = document.querySelector('#one') //querySelector()寻找对象
const two = document.querySelector('#two')
const three = document.querySelector('#three')
one.innerHTML = arr[random] //innerHTML() 修改对象里面的内容
arr.splice(random, 1)
const random2 = Math.floor(Math.random() * arr.length)
two.innerHTML = arr[random]
arr.splice(random2, 1)
const random3 = Math.floor(Math.random() * arr.length)
three.innerHTML = arr[random3]
</script>
</body>
</html>
WebAPIS
DOM-文件对象模型
直观的体现了标签与标签之间的关系
核心思想:把网页内容当作对象来处理
用css选择器获取dom元素
document.querySelector('css选择器')
document.querySelectorAll()
nav.style.color = 'red' 可以修改颜色
操作元素内容
- innerText:不解析标签
- innerHTML:会解析标签
修改样式 是用style修改的
- className
- classList.add 添加样式 remove 删除样式 不加.
toggle 切换样式 有就删掉 没有就加上
定时器
间歇函数 let 变量名 = setInterval(函数,间隔时间)
关闭定时器 clearInterval(变量名)
例子三 定时轮播图
<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')
const footer = document.querySelector('.slider-footer')
let i = 0
setInterval(function () {
i++
if (i == sliderData.length) {
i = 0
}
img.src = sliderData[i].url
p.innerHTML = sliderData[i].title
footer.style.backgroundColor = sliderData[i].color
document.querySelector(`.slider-indicator .active`).classList.remove('active')
document.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')
}, 1000)
</script>
2024.5.22
事件监听
利用程序检测是否有事件产生,一旦有事件出发,就立即调用一个函数做出响应
三要素:
- 事件源:谁被触发
- 事件类型:用什么方式出发
- 事件处理程序:要做什么事情
addEventListener(‘事件类型’,要执行的函数)
eg: btn.addEventListener('click',function(){
button.style.display = 'none'})
on方式会被覆盖 addel方法就可以绑定多个事件,拥有时间更多特性因此更适合使用
常用的事件类型:
- click
- mouseleave
- mouseenter
- focus
- blur
- keydown
- keyup
- input 用户输入事件 total.value.length(可以获取输入长度)
事件对象
也是个对象,这个对象里有时间触发时的相关信息
常见部分属性
- type 当前事件类型
- clientX/clientY 获取光标相对于浏览器可见窗口左上角的位置
- offsetX/offsetY 获取光标相对于当前DOM元素左下角的位置
- key 用户按下键盘的值
trim()
会去除左右的空格
环境对象
变量this 代表当前函数运行时所处的环境
谁调用this就指向谁
回调函数
如果将函数A作为参数传递给函数B时,就称为回调函数
今天做的几个例子
1.随机点名 按下开始键时随机滚动 按下停止时显示一个名字,并从数组中删除。当数组只剩下最后一个值时冻结开始停止按钮
<script>
const arr = ['马超', '黄忠', '赵云', '关羽', '张飞']
//<!-- 开始按钮模块 -->
const start = document.querySelector('.btns .start')
const end = document.querySelector('.btns .end')
const qs = document.querySelector('.qs')
let n = 0
let random = 0
start.addEventListener('click', function () {
n = setInterval(function () {
random = Math.floor(Math.random() * arr.length)
qs.innerHTML = arr[random]
}, 100)
//当数组只剩下一个元素时,禁止使用开始和结束按钮
if (arr.length === 1) {
start.disabled = true
end.disabled = true
}
})
//结束按钮模块
end.addEventListener('click', function () {
clearInterval(n)
arr.splice(random, 1)
})
</script>
2.轮播图点击切换,在原先的基础上,划过页面暂停播放,离开页面继续播放,点击左键会切换到上一页,点击右键会切换到下一页
<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 all = document.querySelector('.slider')
const left = document.querySelector('.prev')
const right = document.querySelector('.next')
const img = document.querySelector('.slider-wrapper img')
const p = document.querySelector('.slider-footer p')
const footer = document.querySelector('.slider-footer')
let i = 0
let timer = 0
timer = setInterval(function () {
right.click()
}, 1000)
//给左键点击添加事件
left.addEventListener('click', function () {
i--
//如果小于0 则将i重新置于最大处
if (i < 0) {
i = sliderData.length - 1
}
img.src = sliderData[i].url
p.innerHTML = sliderData[i].title
footer.style.backgroundColor = sliderData[i].color
document.querySelector(`.slider-indicator .active`).classList.remove('active')
document.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')
})
//右键点击事件
right.addEventListener('click', function () {
i++
//如果i为最大值 则重新置于0
if (i == sliderData.length) {
i = 0
}
img.src = sliderData[i].url
p.innerHTML = sliderData[i].title
footer.style.backgroundColor = sliderData[i].color
document.querySelector(`.slider-indicator .active`).classList.remove('active')
document.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')
})
//鼠标进入事件
all.addEventListener('mouseenter', function () {
clearInterval(timer)
})
//鼠标离开事件
all.addEventListener('mouseleave', function () {
timer = setInterval(function () {
right.click()
}, 1000)
})
</script>
3.小米搜索框 考察focus和blur 当focus定位是显示下拉列表 离开时不显示
<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>
4.评论数字统计 考察input,keyup,trim()和tx.value.length
<script>
const tx = document.querySelector('#tx')
const total = document.querySelector('.total')
const list = document.querySelector('.list')
const item = document.querySelector('.item')
const text = document.querySelector('.text')
//focus聚焦事件
tx.addEventListener('focus', function () {
total.style.opacity = 1
})
//blur事件
tx.addEventListener('blur', function () {
total.style.opacity = 0
})
//input事件
tx.addEventListener('input', function () {
//统计字数,实时更新
total.innerHTML = `${tx.value.length}/200字`
})
//keyup事件
tx.addEventListener('keyup', function (e) {
//当输入的值为Enter时 触发事件
if (e.key === 'Enter') {
//去除左右两边空格
if (tx.value.trim() !== '') {
item.style.display = 'block'
text.innerHTML = tx.value
}
//上传评论后清空value
tx.value = ''
}
})
</script>
5.综合案例
<script>
//1. a模块制作
//先选中所有a
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')
})
}
</script>
2024.5.23
事件流
指的是事件完整执行饿流动路径
捕获阶段
从DOM的根元素去执行对应的事件 从外到里
addEventListener
默认是false 要捕获就设置为true
点击儿子会执行父亲和爷爷
冒泡阶段
默认都是冒泡 会导致事件影响父级元素
阻止冒泡
前提:拿到事件对象
需求:阻止事件冒泡
stopPropagation()
preventDefault()
解绑事件
- on事件
- removeEventListener
mouseover mouseout会发生冒泡现象 最好用mouseenter mouseleave
事件委托
利用事件流特征解决一些开发需求的知识技巧
优点:减少注册次数 可以提高程序性能
原理 利用事件冒泡的特点
e.value.length
e.target 就是点击的对象
e.target.tagName 后面是字符串且必须大写
data-id 自定义属性
其他事件
事件解绑
两种方法
-
on 给on事件添加null属性
-
removeEventListener()
事件委托
e.target.tagName ==="大写" 这种事件才会被选中
案例
<script>
//给li标签添加事件触发
const ul = document.querySelector('ul')
ul.addEventListener('click', function (e) {
if (e.target.tagName === 'LI') {
e.target.style.color = 'red'
}
})
</script>
页面加载事件 DOMContentLoaded
<script>
document.addEventListener('DOMContentLoaded', function () {
const btn = document.querySelector('botton')
btn.addEventListener('click', function () {
alert(11)
})
</script>
页面滚动事件 scroll
<script>
//可以被读写
document.documentElement.scrollTop = 800//不带单位
const div = document.querySelector('div')
window.addEventListener('scroll', function () {
//可以得到向上滚动了多少
console.log(document.documentElement.scrollTop)
if (n >= 100) {
div.style.display = 'block'
} else {
div.style.display = 'none'
}
})
</script>
页面尺寸事件 resize
<script>
const div = document.querySelector('div')
console.log(div.clientHeight)
console.log(div.clientWidth)
//resize 浏览器窗口大小发生变化的时候触发事件
window.addEventListener('resize', function () {
//
})
</script>
今天的几个案例
案例一:点击全选按钮勾选所有按钮 点击全部子按钮则全选按钮被选上
<script>
//id选择器
const checkall = document.querySelector('#checkAll')
const cks = document.querySelectorAll('.check')
checkall.addEventListener('click', function () {
for (let i = 0; i < cks.length; i++) {
cks[i].checked = checkall.checked
}
})
for (let i = 0; i < cks.length; i++) {
cks[i].addEventListener('click', function () {
//伪类选择器
checkall.checked = document.querySelectorAll('.ck:checked').length === cks.length
})
}
</script>
案例二:页面切换 点击切换播放图片
<script>
const ul = document.querySelector('.tab-nav ul')
//获取父亲
ul.addEventListener('click', function (e) {
if (e.target.tagName == 'A') {
document.querySelector('.tab-nav .active').classList.remove('active')
e.target.classList.add('active')
document.querySelector('.tab-content .active').classList.remove('active')
//这里要转换成数字类型
const i = +e.target.dataset.id
document.querySelector(`.tab-content .item:nth-child${i + 1}`).add('active')
}
})
</script>
案例三:仿新浪固定头部 当滑到一定top值固定头部页面
<script>
const header = document.querySelector('.header')
const sk = document.querySelector('.sk')
window.addEventListener('scroll', function () {
const n = document.documentElement.scrollTop
if (n >= sk.offsetTop) {
sk.style.top = 0
} else {
sk.style.top = '-80px'
}
})
</script>
案例四:电梯导轨
<script>
//第一大模块 页面滑动可以显示和隐藏
(function () {
//获取元素
const entry = document.querySelector('.xtx_entry')
//当滚动距离大于300时显示
const elevator = document.querySelector('.xtx-elevator')
window.addEventListener('scroll', function () {
const n = document.documentElement.scrollTop
elevator.style.opacity = n >= entry.offsetTop ? 1 : 0
})
//点击返回页面顶部
const backTop = document.querySelector('#backTop')
backTop.addEventListener('click', function () {
window.scrollTo(0, 0)
})
})();
//第二大模块
(function () {
const list = document.querySelector('.xtx-elevator-list')
list.addEventListener('click', function (e) {
if (e.target.tagName === 'A' && e.target.dataset.name) {
//document.querySelector('.xtx-elevator-list .active').classList.remove('active')
//不能直接获取这个类
const old = document.querySelector('.xtx-elevator-list .active')
if (old) old.classList.remove('active')
e.target.classList.add('active')
const top = document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop
//让页面滚动
document.documentElement.scrollTop = top
}
})
window.addEventListener('scroll', function () {
const old = document.querySelector('.xtx-elevator-list .active')
if (old) old.classList.remove('active')
//当在此区域时,侧边栏显示区域名称
const news = document.querySelector('.xtx_goods_new')
const populer = document.querySelector('.xtx_goods_popular')
const brand = document.querySelector('.xtx_goods_brand')
const topic = document.querySelector('.xtx_goods_topic')
//获得当前滚动值
const n = document.documentElement.scrollTop
if (n >= news.offsetTop && n < populer.offsetTop) {
document.querySelector('[data-name=new]').classList.add('active')
} else if (n >= populer.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')
}
})
})();
</script>
2024.5.24
事件对象
const date = new Date()
日期对象方法
能够使用日期对象中的方法写出常见的日期格式
getMonth() 取值范围是0~11 getDay()获得星期 因此这两个都要加上一
时间表示格式的几种方式
- date.toLocaleString() xxxx/xx/xx xx:xx:xx
- date.toLocaleDateString() xxxx/xx/xx
- date.toLocaleTimeString() xxxx/xx/xx
时间戳
能够获得当前时间戳
指的从1970年起到现在的毫秒数
三种方式
- getTime()
- **+new Date()**
- Date.now() 只能获得当前的
节点操作
对标签进行增删改查
Dom节点 dom树里面的每一个内容
节点类型
- - 元素节点 可以让我们理清标签元素之间的关系
所有的标签 body div
html是根节点
- - 属性节点
所有的属性 href
- - 文本节点
所有的文本
- - 其他
查找节点
利用节点之间的关系
- 父节点查找 son.parentNode
- 子节点 ul.children
- 兄弟节点 nextElementSibling previousElementSibling
添加节点
document.createElement('div')
fu.appendchild 插入到最后
fu.insertBefore(要插入的元素,在哪个元素之前)
克隆节点 ele.cloneElement
删除节点 fu.removeChild
M端事件 移动端事件
- touchstart
- touchmove
- touchend
今日案例
案例一:点击关闭案例,利用孩子对父亲进行操作 parentNode
<script>
/* const box1 = document.querySelector('.box1')
box1.addEventListener('click', function () {
this.parentNode.style.display = 'none'
}) */
const closeBtn = document.querySelectorAll('.box1')
for (let i = 0; i < closeBtn.length; i++) {
closeBtn[i].addEventListener('click', function () {
//点击孩子,隐藏父亲模块
this.parentNode.style.opacity = 0
})
}
</script>
案例二:毕业倒计时效果 用+new Date() 获得时间戳
<script>
//随机颜色函数
function getRandomColor(flag = true) {
if (flag) {
let str = '#'
let arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
for (let i = 1; i <= 6; i++) {
let random = Math.floor(Math.random() * arr.length)
str += arr[random]
}
return str
} else {
let r = Math.floor(Math.random() * 256)
let b = Math.floor(Math.random() * 256)
let g = Math.floor(Math.random() * 256)
return `rgb(${r},${g},${b})`
}
}
const countdown = document.querySelector('.countdown')
countdown.style.backgroundColor = getRandomColor()
//倒计时模块
function getCountTime() {
const hour = document.querySelector('#hour')
const minutes = document.querySelector('#minutes')
const second = document.querySelector('#scond')
//得到当前的时间戳
const now = +new Date()
//得到将来的时间戳
const last = +new Date('2024-05-25 18:30:00')
//剩余的时间戳
const count = (last - now) / 1000
let h = parseInt(count / 60 / 60 % 24)
let m = parseInt(count / 60 % 60)
let s = parseInt(count % 60)
h = h < 10 ? '0' + h : h
m = m < 10 ? '0' + m : m
s = s < 10 ? '0' + s : s
hour.innerHTML = h
minutes.innerHTML = m
second.innerHTML = s
}
getCountTime()
setInterval(getCountTime, 1000)
</script>
案例三 学成在线案例 利用父亲添加孩子 createElement()
<script>
// 1. 重构
let data = [
{
src: 'images/course01.png',
title: 'Think PHP 5.0 博客系统实战项目演练',
num: 1125
},
{
src: 'images/course02.png',
title: 'Android 网络动态图片加载实战',
num: 357
},
{
src: 'images/course03.png',
title: 'Angular2 大前端商城实战项目演练',
num: 22250
},
{
src: 'images/course04.png',
title: 'Android APP 实战项目演练',
num: 389
},
{
src: 'images/course05.png',
title: 'UGUI 源码深度分析案例',
num: 124
},
{
src: 'images/course06.png',
title: 'Kami2首页界面切换效果实战演练',
num: 432
},
{
src: 'images/course07.png',
title: 'UNITY 从入门到精通实战案例',
num: 888
},
{
src: 'images/course08.png',
title: 'Cocos 深度学习你不会错过的实战',
num: 590
},
]
//获得父亲
const ul = document.querySelector('.box-bd ul')
for (let i = 0; i < data.length; i++) {
//创建孩子
const li = document.createElement('li')
//
li.innerHTML = `
<a href="#">
<img src = ${data[i].src}>
<h4>
${data[i].title}
</h4>
<div class="info">
<span>高级</span>·<span>${data[i].num}</span>人在学习
</div>
</a>
`
//父亲加入孩子到最后 insertBefore()是加在最前面
ul.appendChild(li)
}
</script>
案例四:学生信息管理 综合案例
<script>
// 获取元素
const uname = document.querySelector('.uname')
const age = document.querySelector('.age')
const gender = document.querySelector('.gender')
const salary = document.querySelector('.salary')
const city = document.querySelector('.city')
const tbody = document.querySelector('tbody')
// 获取所有带有name属性的元素
const items = document.querySelectorAll('[name]')
// 声明一个空的数组, 增加和删除都是对这个数组进行操作
const arr = []
// 1. 录入模块
// 1.1 表单提交事件
const info = document.querySelector('.info')
info.addEventListener('submit', function (e) {
// 阻止默认行为 不跳转
e.preventDefault()
// 这里进行表单验证 如果不通过,直接中断,不需要添加数据
// 先遍历循环
for (let i = 0; i < items.length; i++) {
if (items[i].value === '') {
return alert('输入内容不能为空')
}
}
// 创建新的对象
const obj = {
stuId: arr.length + 1,
uname: uname.value,
age: age.value,
gender: gender.value,
salary: salary.value,
city: city.value
}
// 追加给数组里面
arr.push(obj)
// 清空表单 重置
this.reset()
// 调用渲染函数
render()
})
// 2. 渲染函数 因为增加和删除都需要渲染
function render() {
// 先清空tbody 以前的行 ,把最新数组里面的数据渲染完毕
tbody.innerHTML = ''
// 遍历arr数组
for (let i = 0; i < arr.length; i++) {
// 生成 tr
const tr = document.createElement('tr')
tr.innerHTML = `
<td>${arr[i].stuId}</td>
<td>${arr[i].uname}</td>
<td>${arr[i].age}</td>
<td>${arr[i].gender}</td>
<td>${arr[i].salary}</td>
<td>${arr[i].city}</td>
<td>
<a href="javascript:" data-id=${i}>删除</a>
</td>
`
// 追加元素 父元素.appendChild(子元素)
tbody.appendChild(tr)
}
}
// 3. 删除操作
// 3.1 事件委托 tbody
tbody.addEventListener('click', function (e) {
if (e.target.tagName === 'A') {
// 得到当前元素的自定义属性 data-id
// 删除arr 数组里面对应的数据
arr.splice(e.target.dataset.id, 1)
// 重新渲染一次
render()
}
})
</script>
2024.5.26
BOM 浏览器对象模型windows
定时器-延时函数SetTimeout()
只执行一次,可以理解为把一段代码延迟执行
每次调用延时器都会产生一个新的延时器,返回是一个数字
js的执行机制
单线程:同一时间制作一件事情
利用多核CPU的计算能力,HTML5提出了web worker标准,用于js脚本创建多个线程,于是提出了同步和异步
- 同步:前一个任务结束后再执行后一个任务,执行顺序和任务的排列顺序是一致的
- 同步任务:都在主线程上执行,形成一个执行栈
- 异步:在做一件事情的同时,可以去处理其他事情
- 异步任务:通过回调函数实现的,异步任务相关条件到任务队列中(消息队列),eg:click resize load error setInterval setTimeout
事件循环(event loop):执行机制:(1)先执行执行栈中的同步任务 (2)异步任务放入任务队列中 (3)一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。由于主线程不断的重复获得任务、执行任务、再获取任务、再执行这种机制被称为事件循环
都是132
location对象
location的数据类型是对象,它拆分并保存了URL地址的各个组成部分
- location.search 返回?后面的属性
- location.href :实现页面跳转
- location.hash 获得#后面的部分
- reload(true) 刷新当前的页面 是一个方法
navigator对象
<script>
// 检测 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'
}
})();
// !(function () { })();
!function () { }()
</script>
history对象
- back() 后退
- forward() 前进功能
- go(参数)
本地存储
什么是本地存储:数据存储在用户浏览器中
本地存储分类
localstorage
能够使用localstorage把数据存储在浏览器中
作用:可以将数据永久存储在本地,除非手动删除,否则关闭页面也会存在
特性:多窗口共享 以键值对的形式存储
语法:
- 存储数据:localStorage.setItem(key,value)
- 得到数据:localStorage.getItem('uname')
- 删除数据:localStorage.removeItem('uname')
- 修改数据:localStorage.setItem('uname','red)
本地存储分类 sessionStorage
生命周期为关闭浏览器窗口 使用方法和localStorage基本相同
存储复杂数据类型
- 无法直接使用,首先使用JSON.stringify(obj)
- 再转回去JSON.parse(localStorage.getItem('obj'))
拼接map() join() 一般两个连用
map有返回值,但是foreach没有返回值、
join将数组中的所有元素转换一个字符串
今日案例
案例一:五秒之后广告自动消失 考察setTimeout()
<script>
let img = document.querySelector('img')
let n = setTimeout(function () {
img.style.display = 'none'
}, 5000)
</script>
案例二:五秒自动跳转网站 考察setInverval location.href
<script>
const a = document.querySelector('a')
let num = 5
let n = setInterval(function () {
num--
a.innerHTML = `支付成功<span>${num}</span>秒后跳转网页`
if (num == 0) {
//停止计时器
clearInterval(n)
//完成自动跳转
location.href = 'http://www.baidu.com'
}
}, 1000)
</script>
案例三:综合案例 学生信息表 考察localStorage.setItem map join confirm arr[arr.length-1].stuId+1
<script>
// 参考数据
//const initData = [
// {
// stuId: 1001,
// uname: '欧阳霸天',
// age: 19,
// gender: '男',
// salary: '20000',
// city: '北京',
// time: '2024/5/26'
// }
//]
//localStorage.setItem('data', JSON.stringify(initData))
const arr = JSON.parse(localStorage.getItem('data')) || []
const tbody = document.querySelector('tbody')
function render() {
let trArr = arr.map(function (ele, index) {
//添加自定义属性方便后续处理
return `
<tr>
<td>${ele.stuId}</td>
<td>${ele.uname}</td>
<td>${ele.age}</td>
<td>${ele.gender}</td>
<td>${ele.salary}</td>
<td>${ele.city}</td>
<td>${ele.time}</td>
<td>
<a href="javascript:" data-id = "${index}">删除</a>
</td>
</tr> `
})
tbody.innerHTML = trArr.join('')
document.querySelector('.title span').innerHTML = arr.length
}
//重新渲染
render()
//进行元素添加
const info = document.querySelector('.info')
const uname = document.querySelector('.uname')
const age = document.querySelector('.age')
const salary = document.querySelector('.salary')
const gender = document.querySelector('.gender')
const city = document.querySelector('.city')
info.addEventListener('submit', function (e) {
e.preventDefault()
if (!uname.value || !age.value || !salary.value) {
return alert('输入内容不能为空')
}
arr.push({
stuId: arr.length ? [arr.length - 1].stuId + 1 : 1,
uname: uname.value,
age: age.value,
gender: gender.value,
salary: salary.value,
city: city.value,
time: new Date().toLocaleString()
})
this.reset()
render()
localStorage.setItem('data', JSON.stringify(arr))
})
tbody.addEventListener('click', function (e) {
if (e.target.tagName === 'A') {
console.log(e.target.dataset.id)
if (confirm('您确定要删除这条数据吗?')) {
arr.splice(e.target.dataset.id, 1)
render()
localStorage.setItem('data', JSON.stringify(arr))
}
}
})
</script>