日期对象
目标:掌握日期对象,可以让网页显示日期
日期对象:用来表示时间的对象
作用:可以得到当前系统时间
学习路径:
-
实例化
-
日期对象方法
-
时间戳
实例化
目标:能够实例化日期对象
在代码中发现了 new 关键字时,一般将这个操作称为实例化
创建一个时间对象并获取时间
获得当前时间
获得指定时间
实战
<!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>
<script>
// 实例化 new
// 1. 得到当前时间
const date = new Date()
console.log(date)
// 2. 指定时间
const date1 = new Date('2022-5-1 08:30:00')
console.log(date1)
</script>
</body>
</html>
日期对象方法
目标:能够使用日期对象中的方法写出常见日期
使用场景:因为日期对象返回的数据我们不能直接使用,所以需要转换为实际开发中常用的格式
实战
<!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>
<script>
// 获得日期对象
const date = new Date()
// 使用里面的方法
console.log(date.getFullYear())
console.log(date.getMonth() + 1) // 月份要 + 1
console.log(date.getDate())
console.log(date.getDay()) // 星期几
</script>
</body>
</html>
实战
时间戳
使用场景: 如果计算倒计时效果,前面方法无法直接计算,需要借助于时间戳完成
什么是时间戳:
是指1970年01月01日00时00分00秒起至现在的毫秒数,它是一种特殊的计量时间的方式
算法:
将来的时间戳 - 现在的时间戳 = 剩余时间毫秒数
剩余时间毫秒数 转换为 剩余时间的 年月日时分秒 就是 倒计时时间
比如 将来时间戳 2000ms - 现在时间戳 1000ms = 1000ms
1000ms 转换为就是 0小时0分1秒
三种方式获取时间戳:
1 使用 getTime() 方法
2 简写 +new Date()
3 使用 Date.now()
无需实例化
但是只能得到当前的时间戳, 而前面两种可以返回指定时间的时间戳
实战
<!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>
<script>
// 1. getTime()
const date = new Date()
console.log(date.getTime())
// 2. +new Date()
console.log(+new Date())
// 3. Date.now()
console.log(Date.now());
// 2. +new Date()
console.log(+new Date())
console.log('-----------------');
console.log(+new Date('2022-4-1 18:30:00'))
// 我要根据日期 Day() 0 ~ 6 返回的是 星期一
const arr = ['星期天', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
// const date = new Date()
console.log(arr[new Date().getDay()])
</script>
</body>
</html>
效果
节点操作
DOM节点
DOM树里每一个内容都称之为节点
节点类型
元素节点
所有的标签 比如 body、 div,html 是根节点
属性节点
所有的属性 比如 href
文本节点
所有的文本
其他节点
查找节点
关闭二维码案例:
点击关闭按钮, 关闭的是二维码的盒子, 还要获取erweima盒子
思考:
关闭按钮 和 erweima 是什么关系呢?答:父子关系
所以,我们完全可以这样做:点击关闭按钮, 直接关闭它的爸爸,就无需获取erweima元素了
节点关系:针对的找亲戚返回的都是对象
有以下节点:父节点 子节点 兄弟节点
父节点查找:
parentNode 属性
返回最近一级的父节点 找不到返回为null
实战
<!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: pink;
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>
<div class="box">
我是广告
<div class="box1">X</div>
</div>
<div class="box">
我是广告
<div class="box1">X</div>
</div>
<script>
// // 1. 获取事件源
// const box1 = document.querySelector('.box1')
// // 2. 事件侦听
// box1.addEventListener('click', function () {
// this.parentNode.style.display = 'none'
// })
// 1. 获取三个关闭按钮
const closeBtn = document.querySelectorAll('.box1')
for (let i = 0; i < closeBtn.length; i++) {
closeBtn[i].addEventListener('click', function () {
// 关闭我的爸爸 所以只关闭当前的父元素
this.parentNode.style.display = 'none'
})
}
</script>
</body>
</html>
子节点查找
childNodes:
获得所有子节点、包括文本节点(空格、换行)、注释节点等
children 属性 (重点)
仅获得所有元素节点,返回的还是一个伪数组
语法
实战
<!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>
</ul>
<script>
const ul = document.querySelector('ul') // ul
console.log(ul.children) // 得到伪数组 选择的是 亲儿子
</script>
</body>
</html>
效果
兄弟关系查找
1 下一个兄弟节点
nextElementSibling 属性
2 上一个兄弟节点
previousElementSibling 属性
实战
<!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>
</ul>
<script>
// const ul = document.querySelector('ul') // ul
// console.log(ul.children) // 得到伪数组 选择的是 亲儿子
const li2 = document.querySelector('ul li:nth-child(2)')
console.log(li2.previousElementSibling) // 上一个兄弟
console.log(li2.nextElementSibling) // 下一个兄弟
</script>
</body>
</html>
增加节点
很多情况下,我们需要在页面中增加元素
比如,点击发布按钮,可以新增一条信息
一般情况下,我们新增节点,按照如下操作:
创建一个新的节点 把创建的新的节点放入到指定的元素内部
学习路线:
创建节点 追加节点
创建节点
即创造出一个新的网页元素,再添加到网页内,一般先创建节点,然后插入节点
创建元素节点方法:
追加节点
要想在界面看到,还得插入到某个父元素中
插入到父元素的最后一个子元素:
插入到父元素中某个子元素的前面
实战
<!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>我是老大</li>
</ul>
<script>
// // 1. 创建节点
// const div = document.createElement('div')
// // console.log(div)
// 2. 追加节点 作为最后一个子元素
// document.body.appendChild(div)
const ul = document.querySelector('ul')
const li = document.createElement('li')
li.innerHTML = '我是li'
ul.appendChild(li)
// ul.children
// 3. 追加节点
// insertBefore(插入的元素, 放到哪个元素的前面)
// ul.insertBefore(li, ul.children[0])
</script>
</body>
</html>
效果
克隆节点
特殊情况下,我们新增节点,按照如下操作:
复制一个原有的节点
把复制的节点放入到指定的元素内部
cloneNode会克隆出一个跟原标签一样的元素,括号内传入布尔值
若为true,则代表克隆时会包含后代节点一起克隆
若为false,则代表克隆时不包含后代节点
默认为false
实战
<!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>
</ul>
<script>
const ul = document.querySelector('ul');
// 1. 克隆节点
const li1 = ul.children[0].cloneNode(true);
// 2. 创建后代元素(例如一个 <span>)
const span = document.createElement('span');
span.textContent = ' - 后代元素'; // 设置 <span> 的内容
span.style.color = 'red'; // 可选:设置样式
// 3. 将 <span> 追加到克隆的 <li> 中
li1.appendChild(span);
// 4. 将克隆并修改后的 <li> 追加到 <ul> 中
ul.appendChild(li1);
</script>
</body>
</html>
删除节点
若一个节点在页面中已不需要时,可以删除它
在 JavaScript 原生DOM操作中,要删除元素必须通过父元素删除
语法
注:
如不存在父子关系则删除不成功
删除节点和隐藏节点(display:none) 有区别的: 隐藏节点还是存在的,但是删除,则从html中删除节点
实战
<!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 {
background-color: pink;
width: 50%;
height: 500px;
}
</style>
</head>
<body>
<div class="box">123</div>
<ul>
<li>没用了</li>
</ul>
<script>
const ul = document.querySelector('ul')
// 删除节点 父元素.removeChlid(子元素)
ul.removeChild(ul.children[0])
</script>
</body>
</html>
效果
M端事件
移动端也有自己独特的地方。比如触屏事件 touch(也称触摸事件),Android 和 IOS 都有。
触屏事件 touch(也称触摸事件),Android 和 IOS 都有。
touch 对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。触屏事件可响应用户手指(或触控笔 )对屏幕或者触控板操作。
常见的触屏事件如下
window对象
BOM
BOM 浏览器对象模型,定义了一套操作浏览器窗口的API
BOM (Browser Object Model ) 是浏览器对象模型
-
window对象是一个全局对象,也可以说是JavaScript中的顶级对象
-
像document、alert()、console.log()这些都是window的属性,基本BOM的属性和方法都是window的
-
所有通过var定义在全局作用域中的变量、函数都会变成window对象的属性和方法
-
window对象下的属性和方法调用的时候可以省略window
定时器-延迟函数
JavaScript 内置的一个用来让代码延迟执行的函数,叫 setTimeout
语法:
javascript">setTimeout(回调函数, 延迟时间)
setTimeout 仅仅只执行一次,所以可以理解为就是把一段代码延迟执行, 平时省略window
间歇函数 setInterval : 每隔一段时间就执行一次, , 平时省略window
清除延时函数:
javascript">clearTimeout(timerId)
注意点
延时函数需要等待,所以后面的代码先执行
返回值是一个正整数,表示定时器的编号
实战
<!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>
<script>
setTimeout(function () {
console.log('时间到了')
}, 2000)
</script>
</body>
</html>
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 等
异步任务相关添加到任务队列中(任务队列也称为消息队列)。
案例解读:
问下面的执行顺序是什么
1 先执行执行栈中的同步任务。
2 异步任务放入任务队列中。
3 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。
执行机制
1. **主线程和执行栈**:
- JavaScript 是单线程的,主线程负责执行代码。
- 代码执行时,会按照顺序将任务推入执行栈中执行。
2. **异步任务处理**:
- 当遇到异步任务(如 `ajax`、`DOM 事件`、`setTimeout` 等)时,主线程会将任务提交给对应的异步模块处理(如网络模块、DOM 模块、定时器模块等)。
- 异步任务完成后,会将回调函数推入任务队列中。
3. **任务队列**:
- 任务队列分为多个队列,例如:
- 任务队列1:`onload`、`onclick` 等 DOM 事件。
- 任务队列2:`setTimeout`、`setInterval` 等定时器任务。
- 任务队列3:网络请求(如 `ajax`)的回调。
4. **事件循环(Event Loop)**:
- 主线程执行完所有同步任务后,会检查任务队列。
- 如果任务队列中有任务,主线程会取出一个任务推入执行栈中执行。
- 这个过程会不断重复,称为事件循环。
5. **异步任务完成后的处理**:
- 异步任务完成后,会将回调函数推入任务队列中,等待主线程处理。
概括总结
JavaScript 的执行机制可以概括为:
- **同步任务**:在主线程中按顺序执行。
- **异步任务**:由对应的异步模块处理,完成后将回调推入任务队列。
- **事件循环**:主线程不断从任务队列中取出任务并执行,确保异步任务得到处理。
这种机制使得 JavaScript 能够高效处理异步操作,同时保持单线程的特性。
图片描述:
location对象
location (地址) 它拆分并保存了 URL 地址的各个组成部分, 它是一个对象
属性/方法 | 说明 |
---|---|
href | 属性,获取完整的 URL 地址,赋值时用于地址的跳转 |
search | 属性,获取地址中携带的参数,符号 ?后面部分 |
hash | 属性,获取地址中的啥希值,符号 # 后面部分 |
reload() | 方法,用来刷新当前页面,传入参数 true 时表示强制刷新 |
实战
<!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>
<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>
console.log(window.location)
console.log(location)
console.log(location.href)
// 1. href 经常用href 利用js的方法去跳转页面
// location.href = 'http://www.baidu.com'
console.log(location.search);
window.addEventListener('hashchange', function () {
console.log('哈希值变化为:', location.hash);
});
const reload = document.querySelector('.reload')
reload.addEventListener('click', function () {
// f5 刷新页面
// location.reload()
// 强制刷新 ctrl+f5
location.reload(true)
})
</script>
</body>
</html>
部分效果:
navigator对象
navigator是对象,该对象下记录了浏览器自身的相关信息
常用属性和方法:
-
通过 userAgent 检测浏览器的版本及平台
实战
<!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>
// 检测 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>
</head>
<body>
这是pc端的页面
<script>
// (function () { })()
</script>
</body>
</html>
histroy对象
history (历史)是对象,主要管理历史记录, 该对象与浏览器地址栏的操作相对应,如前进、后退等
使用场景
history对象一般在实际开发中比较少用,但是会在一些OA 办公系统中见到。
常见方法:
浏览器这里可以后退,就是用history实现的
实战
<!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>
<button>后退</button>
<button>前进</button>
<script>
const back = document.querySelector('button:first-child')
const forward = back.nextElementSibling
back.addEventListener('click', function () {
// 后退一步
// history.back()
history.go(-1)
})
forward.addEventListener('click', function () {
// 前进一步
// history.forward()
history.go(1)
})
</script>
</body>
</html>
本地存储
本地存储介绍
以前我们页面写的数据一刷新页面就没有了,是不是?
随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,HTML5规范提出了相关解决方案。
1、数据存储在用户浏览器中
2、设置、读取方便、甚至页面刷新不丢失数据
3、容量较大,sessionStorage和localStorage约 5M 左右
本地存储分类- localStorage
作用: 可以将数据永久存储在本地(用户的电脑), 除非手动删除,否则关闭页面也会存在
特性:
可以多窗口(页面)共享(同一浏览器可以共享)
以键值对的形式存储使用
本地存储分类
localStorage(重点)
语法:
存储数据:
localStorage.setItem(key, value)
获取数据:
localStorage.getItem(key)
删除数据:
localStorage.removeItem(key)
实战
<!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>
<script>
// 1. 要存储一个名字 'uname', 'pink老师'
// localStorage.setItem('键','值')
localStorage.setItem('uname', 'pink老师')
// 2. 获取方式 都加引号
console.log(localStorage.getItem('uname'))
// 3. 删除本地存储 只删除名字
// localStorage.removeItem('uname')
// 4. 改 如果原来有这个键,则是改,如果么有这个键是增
localStorage.setItem('uname', 'red老师')
// 我要存一个年龄
// 2. 本地存储只能存储字符串数据类型
localStorage.setItem('age', 18)
console.log(localStorage.getItem('age'))
</script>
</body>
</html>
效果
sessionStorage(了解)
本地存储分类- sessionStorage
特性:
生命周期为关闭浏览器窗口
在同一个窗口(页面)下数据可以共享
以键值对的形式存储使用
用法跟localStorage 基本相同
语法:
存储:sessionStorage.setItem(key,value)
获取:sessionStorage.getItem(key)
删除:sessionStorage.removeItem(key)
localStorage 存储复杂数据类型
问题1:本地只能存储字符串,无法存储复杂数据类型.
解决:需要将复杂数据类型转换成 JSON字符串,在存储到本地
语法:JSON.stringify(复杂数据类型)
JSON字符串:
-
首先是1个字符串
-
属性名使用双引号引起来,不能单引号
-
属性值如果是字符串型也必须双引号
问题2:因为本地存储里面取出来的是字符串,不是对象,无法直接使用
解决: 把取出来的字符串转换为对象
语法:JSON.parse(JSON字符串)
实战
<!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>
<script>
const obj = {
uname: 'pink老师',
age: 18,
gender: '女'
}
// // 存储 复杂数据类型 无法直接使用
// localStorage.setItem('obj', obj) [object object]
// // 取
// console.log(localStorage.getItem('obj'))
// 1.复杂数据类型存储必须转换为 JSON字符串存储
localStorage.setItem('obj', JSON.stringify(obj))
// JSON 对象 属性和值有引号,而是引号统一是双引号
// {"uname":"pink老师","age":18,"gender":"女"}
// 取
// console.log(typeof localStorage.getItem('obj'))
// 2. 把JSON字符串转换为 对象
const str = localStorage.getItem('obj') // {"uname":"pink老师","age":18,"gender":"女"}
console.log(JSON.parse(str))
</script>
</body>
</html>
效果