JavaScript最新
JavaScript最新
Echo1.JavaScript简介
1.1JavaScript 简介
js 是什么
是一种运行在客户端(浏览器)的编程语言,实现人机交互效果.
js 能做什么(作用)
- 网页特效 (监听用户的一些行为让网页作出对应的反馈)
- 表单验证 (针对表单数据的合法性进行判断)
- 数据交互 (获取后台的数据, 渲染到前端)
- 服务端编程 (node.js
js 的组成
1.2 js的书写位置
内部js
理论上写在哪里都可以,但是最好是写在body的最下面。
外部js
后续程序的开发中最常用的一种方式,将逻辑和样式进行了分离,方便代码的复用,维护。
行内js
和css一样写在标签内的js,前期用的少,后期学到vue用的会非常多。
1
2
3
4
5
6
7
8
9
10
11
12
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button onclick="alert('我是行内的js')">按钮</button>
<script src="wb.js"></script>
</body>
</html>
1.3JavaScript注释
单行注释
- 符号://
- 作用://右边这一行的代码会被忽略
- 快捷键:ctrl +
多行注释
- 符号:/* /
- 作用:在/* 和 */ 之间的所有内容都会被忽略
- 快捷键:shift + alt + A
1.4JavaScript结束符号
- 作用: 使用英文的 ; 代表语句结束
- 实际情况: 实际开发中,可写可不写, 浏览器(JavaScript 引擎) 可以自动推断语句的结束位置 、
- 现状: 在实际开发中,越来越多的人主张,书写 JavaScript 代码时省略结束符
- 约定:为了风格统一,结束符要么每句都写,要么每句都不写(按照团队要求.)
1.5JavaScript的输入输出语法
什么是语法
人与计算机交互的一种规则,我们需要按照 约定好的规则去写程序
输入输出语解释
输出和输入也可理解为人和计算机的交互,用户通过键盘、鼠标等向计算机输入信息,计算机处理后再展示结果给用 户,这便是一次输入和输出的过程。
输出语法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<!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>
<script type="text/javascript">
// 1. 文档出入内容
document.write("我是输出的内容")
document.write("<h1>你好</h1>")
// 2.页面弹出对话框
alert("弹出的对话框")
// 3.控制台
console.log('控制台输出');
</script>
</body>
</html>输入语法
1
2
3
4
5
6<body>
<script type="text/javascript">
// 输入语法
prompt("请输入你的姓名")
</script>
</body>作业:
1.6JavaScript字面量(了解)
在计算机科学中,字面量(literal)是在计算机中描述 事/物 比如:
我们工资是: 1000 此时 1000 就是 数字字面量
‘我是大帅哥’ 字符串字面量
还有接下来我们学的 [] 数组字面量 {} 对象字面量 等等
2.变量与常量
2.1 变量的概念
用户输入的数据我们应该如何存储起来
概念
白话:变量就是一个装东西的盒子
通俗:变量是计算机中用来存储数据的“容器”,它可以让计算机变得有记忆。
注意:变量不是数据本身,它们仅仅是一个用于存储数值的容器。可以理解为是一个个用来装东西的纸箱子。
变量声明
要想使用变量,首先需要创建变量(也称为声明变量或者定义变量
- 语法
1
2let 变量名
//声明变量有两部分构成:声明关键字、变量名(标识)声明变量有两部分构成:声明关键字、变量名(标识)
let 即关键字 (let: 允许、许可、让、要),所谓关键字是系统提供的专门用来声明(定义)变量的词语.
变量的赋值
定义了一个变量后,你就能够初始化它(赋值)。在变量名之后跟上一个“=”,然后是数值
注意:是通过变量名来获得变量里面的数据
变量的初始化
简单点,也可以声明变量的时候直接完成赋值操作,这种操作也称为 变量初始化。
1
2
3 let age=100;
alert(age)
变量练习
2.2变量的基本使用
掌握变量的更新以及了解同时声明多个变量的写法
变量的更新
更新age的值
1
2
3
4
5let age=100;
age=20;
//let age=100;
//使用let修饰的变量就不能重复声明声明多个变量
1
2let a=100,b=10;
//声明多个变量 虽然这样写比较简答, 但是不提倡这样声明,这样的话不利于代码的语义化输入用户名称然后弹出案例
- 用户输入数据
- 将数据保存下来
- 将数据打印下来
1
2
3
4
5
6
7
8<body>
<script>
let name
name= prompt("请输入用户名")
alert(name)
</script>
</body>交换变量案例
有2个变量: num1 里面放的是 10, num2 里面放的是20 最后变为 num1 里面放的是 20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<script>
let a=100;
let b=200;
let c
debugger
c=a
debugger
a=b
debugger
b=c
debugger
console.log('a=',a,'b=',b);
</script>
2.3 变量的本质
内存:是计算机中存储数据的的地方,相当于是一个空间
变量的本质:就是程序在内存中申请一个空间来存储数据
2.4 变量的命名规范与规则
规则:必须遵守,不遵守报错 (法律层面)
规范:建议,不遵守不会报错,但不符合业内通识 (道德层面
规则
- 不能用关键字:有特殊含义的字符,JavaScript 内置的一些英语词汇。例如:let、var、if、for等
- 只能用下划线、字母、数字、$组成,且数字不能开头\
- 字母严格区分大小写,如 Age 和 age 是不同的变量
规范
- 起名要有意义
- 遵守小驼峰命名法:第一个单词首字母小写,后面每个单词首字母大写。例:userName
练习1:以下哪些不符合规范
练习2
1
2
3
4
5
6
7<body>
<script>
let name= prompt("请输入姓名")
let age=prompt("请输入年龄")
alert(`欢迎${name},${age}`)
</script>
</body>
2.5 let和var 的区别
在较旧的JavaScript,使用关键字 var 来声明变量 ,而不是 let。 var 现在开发中一般不再使用它,只是我们可能再老版程序中看到它。 let 为了解决 var 的一些问题
var关键字的一些问题
- 可以先使用 在声明 (不合理)
- var 声明过的变量可以重复声明(不合理)
- 比如变量提升、全局变量、没有块级作用域等等
结论
使用var关键字会给我们的程序编写带来很多的问题,所以我们现在基本都是使用let来代替var,但是在一些较为古老的程序中我们依然可以看到var的存在,所以关于var 我们需要做一些简单的了解。
2.6 数组
变量一次只能存几个值? 如果我想保存一个班里5个人的姓名怎么办?
声明数组
1
let arr=["张三","李四","王五"]
数组简介
- 数组是按顺序保存,所以每个数据都有自己的编号
- 计算机中的编号从0开始
- 在数组中,数据的编号也叫索引或下标
- 数组可以存储任意类型的数据
- 数组中数据的个数,通过数组的length属性获得,叫做数组的长度
使用数组
1
2
3// 读取数组中的第二个元素,数组的下标是从0 开始的,
let two=arr[1]
console.log(arr[2])数组取值作业
需求:定义一个数组,里面存放星期一、星期二…… 直到星期日(共7天),在控制台输出:星期日
2.7 常量
概念:使用 const 声明的变量称为“常量”。
使用场景:当某个变量永远不会改变的时候,就可以使用 const 来声明,而不是let。
命名规范:和变量一致
常量的值不能被修改,声明的时候必须要赋值
常量使用:
1
2
3
4
5//声明一个常量
const A=100;
log(A)
A=200;//如果使用const关键字声明的常量的值放生了改变,那么浏览器就一定会报错
3.数据类型
计算机程序可以处理大量的数据,为什么要给数据分类?
- 更加充分和高效的利用内存 2. 也更加方便程序员的使用数
3.1数据类型分类
js的数据类型主要是分为两类
- 基本数据类型
- 引用数据类型
弱数据类型的语言
js是弱数据类型的语言,java是强数据类型的语言。
js只有当我们赋值了才知道是什么类型的数据。弱数据类型的语言学习起来比较简单
3.32数字类型Number
- 数字可以有很多操作,比如,乘法 * 、除法 / 、加法 + 、减法 - 等等,所以经常和算术运算符一起。 数学运算符也叫算术运算符,主要包括加、减、乘、除、取余(求模)
- +:求和
- -:求差
- *:求积
- /:求商
- %:取模(取余数) 开发中经常作为某个数字是否被整除
同时使用多个运算符编写程序时,会按着某种顺序先后执行,我们称为优先级。 JavaScript中 优先级越高越先被执行,优先级相同时以书从左向右执行
- 乘、除、取余优先级相同
- 加、减优先级相同
- 乘、除、取余优先级大于加、减
- 使用 () 可以提升优先级
- 总结: 先乘除后加减,有括号先算括号里面的~~
案例:计算圆的面积
需求: 弹出输入框,邀请用户输入半径r,然后弹出输入圆的面积
1
2
3
4
5
6
7<script>
// 1. 用户输入r 半径
let r= prompt("请输入圆的半径")
let mianji=3.14*r*r
document.write(mianji)
</script>
</body>
3.3 字符串类型string
通过单引号( ‘’) 、双引号( “”)或反引号( ` ) 包裹的数据都叫字符串,单引号和双引号没有本质上的区别,推 荐使用单引号
1
2
3
4let name='张三'
let age="20"
let goods=`小米`
let str=''注意
- 无论单引号或是双引号必须成对使用
- 单引号/双引号可以互相嵌套,但是不以自已嵌套自已(口诀:外双内单,或者外单内双)
- 必要时可以使用转义符 \,输出单引号或双引号
字符串拼接(数字相加,字符相连)
+ 运算符 可以实现字符串的拼接
1
2
3
4
5log('我是'+'张三')
let name='张三'
let age='23'
log(name+age)模板字符串
使用场景:拼接字符串和变量,在没有它之前,要拼接变量比较麻烦
- `` (反引号) 在英文输入模式下按键盘的tab键上方那个键(1左边那个键)
- 内容拼接变量时,用 ${ } 包住变量
1
2
3log('大家好'+name+'我今年'+age)//普通字符串拼接
log(`大家好我是 ${name} 我今年${age}`)用户输入案例:
需求:需求:页面弹出对话框,输入名字和年龄,页面显示: 大家好,我叫xxx,今年xx岁
3.4 布尔类型 boolean
表示肯定或否定时在计算机中对应的是布尔类型数据。 它有两个固定的值 true 和 false,表示肯定的数据用 true(真),表示否定的数据用 false(假)
1
2
3let istru=true
log(2>8)
3.5未定义类型undefined
声明一个变量但是未给值就叫做未定义
- 未定义是比较特殊的类型,只有一个值 undefined。
- 工作中的使用场景: 我们开发中经常声明一个变量,等待传送过来的数据。 如果我们不知道这个数据是否传递过来,此时我们可以通过检测这个变量是不是undefined,就判断用户是否有数据传递过来
3.6空类型 null
- JavaScript 中的 null 仅仅是一个代表“无”、“空”或“值未知”的特殊值,null是一个对象,如果我们想定义一个对象但是暂时没有值,我们可以先声明一个null类型来占位
- 将来有个变量里面存放的是一个对象,但是对象还没创建好,可以先给个null
3.7 检测数据类型
通过 typeof 关键字检测数据类型
typeof 运算符可以返回被检测的数据类型。它支持两种语法形式:
- 作为运算符: typeof x (常用的写法)
- 函数形式: typeof(x)
1
2
3
4
5let age=16
let name="zhangsan"
let istrue=false
let buy
log(typeof age).....
3.8类型的转换
JavaScript是弱数据类型: JavaScript也不知道变量到底属于那种数据类型,只有赋值了才清楚。 坑: 使用表单、prompt 获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法运算。
1 | log('100'+'100')//100100 输出的结果 |
就是把一种数据类型转换成我们需要的数据类型
隐式数据类型转换
某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换称为隐式转换。
- 号两边只要有一个是字符串,都会把另外一个转成字符串
- 除了+以外的算术运算符 比如 - * / 等都会把数据转成数字类型
1
console.log(1+'1')// '11'
1
2log(2-'1`)// 1
log(+'123')//会转化成为数字类型的123显示数据类型转换
编写程序时过度依靠系统内部的隐式转换是不严谨的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。 为了避免因隐式转换带来的问题,通常根逻辑需要对数据进行显示转换。也就是根据自己的需求将数据转化成为自己需要的类型。
概念:自己写代码将数据转化成为自己需要的类型
Number(数据) –这是一个函数或者叫做方法,可以将数据转化成为我们number类型
- 转成数字类型
- 如果字符串内容里有非数字,转换失败时结果为 NaN(Not a Number)即不是一个数字
- NaN也是number类型的数据,代表非数字
1
console.log(Number('123'))//将字符串类型的123转化成数字类型的123
parseInt(数据)—只要整数
1
2
3
4log(parseInt('12'))// 输出数字类型的12
log(parseInt('12.123'))// 输出数字类型的12
log(parseInt('12.1px'))// 输出数字类型的12
log(parseInt('12px'))// 输出数字类型的12parseFloat(数据)— 包含小数
1
2
3
4log(parseFloat('12'))// 输出数字类型的12
log(parseFloat('12.12'))// 输出数字类型的12.12
log(parseFloat('12.12px'))// 输出数字类型的12
log(parseFloat('asdf1.12'))// 输出数字类型的12练习: 输入两个数的和,打印到页面中;
1
2
3
4
5
6
7
8<script>
let num1=parseInt(prompt("请输入第一个数"))
let num2= parseInt(prompt("请输入第二个数"))
let add=num1+num2
document.write(`<h1>${num1}+${num2}=${add}</h1>`)
</script>
3.9 输入输出综合练习
一个表格,通过输入商品的价格,数量,和收获地址,自动的生成对应的数据
- 静态样式
1 |
|
逻辑
①:需要输入3个数据,所以需要3个变量来存储 price num address
②:需要计算总的价格 total
③:页面打印生成表格,里面填充数据即可
④:记得最好使用模板字符串
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<script>
// 用户输入
let price = + prompt("请输入价格")
let num = + prompt("请输入数量")
let address = prompt("请输入地址")
// 计算总价
let total = price * num
// 页面打印渲染
document.write(
`
<h2>订单信息</h2>
<table>
<tr>
<th>商品名称</th>
<th>商品价格</th>
<th>商品数量</th>
<th>商品总价</th>
<th>发货地址</th>
</tr>
<tr>
<td>商品</td></td>
<td>${price}</td>
<td>${num}</td>
<td>${total}}</td>
<td>${address}</td>
</tr>
</table>
`
)
</script>
4. 运算符
4.1赋值运算符
= 赋值运算符执行过程:将等号右边的值赋予给左边, 要求左边必须是一个容器
对变量进行赋值的运算符
已经学过的赋值运算符:= 将等号右边的值赋予给左边, 要求左边必须是一个容器
其他的赋值运算符
+= += 出现是为了简化代码 num+=5 等同于 num=num+5
-=
*=
/=
%=
1
2
3
4
5
6
7let num=1
num+1
alert(num)// 输出的结果还是1 ,原因是num+1 的值并没有重新赋值给num
// 采用赋值运算符的方式
num+=1//相当于num=mum+1
</script>
4.2一元运算符
我们以前让一个变量每次+1 ,以前我们做的呢?
自减
符号:–
作用:让变量的值 -1
自增
符号:++
作用:让变量的值 +1
使用场景:经常用于计数来使用。 比如进行10次操作,用它来计算进行了多少次了
前置自增和后置自增(了解即可,两者几乎没有区别)
1
2
3let i=1
log(++i+2)//前置自增,i先自增,在和后面的2 相加1
2
3let i=1
log(i++ +2)//后置自增,先和2相加后再自增
4.3比较运算符
比较两个数据大小是否相等
比较运算符
- “>” : 左边是否大于右边
- “<”: 左边是否小于右边
- “>=”: 左边是否大于或等于右边
- “<=”: 左边是否小于或等于右边
- ==: 左右两边值是否相等
- ===: 左右两边是否类型和值都相等
- !==: 左右两边是否不全等\
- 比较结果为boolean类型,即只会得到 true和false
字符串比较,是比较的字符对应的ASCII码
- 从左到右依次比较
- 第一位相同再比较第二位
NaN不等于任何值,包括他本身
不同类型之间会发生隐式转换
最终会把数据隐式转化成为number再进行比较
在开发中,如果要进行比较的话更喜欢用 === 或者!==
4.4 逻辑运算符
逻辑运算符用来解决多重条件判断,如判断 4<num<10 不能这样写,这个时候就需要使用到逻辑运算符
练习判断一个数是4的倍数并且不是100 的倍数
1
2
3
4<script>
let num= parseInt(prompt("请输入一个数字"))
alert(num%4===0&&num%100!==0)
</script>
4.5运算符优先级
5.语句
5.1语句的概念
表达式是可以被求值的代码,JavaScript 引擎会将其计算出一个结果。
1 | x=7 |
语句是一段可以执行的代码
1 | prompt() 可以弹出一个输入框,还有 if语句 for 循环语句等 |
5.2 流程控制语句介绍
以前我们写的代码,写几句就从上往下执行几句,这种叫顺序结构 -
有的时候要根据条件选择执行代码,这种就叫分支结构
某段代码被重复执行,就叫循环结构
5.3 分支语句 if
分支语句可以让我们选择性的执行某一段代码
分支语句包括
- If分支语句
- 三元运算符
- switch 语句
if语句有三种使用:
单分支、双分支、多分支
if 语句的单分支
- 括号内的条件为true时,进入大括号里执行代码
- 小括号内的结果若不是布尔类型时,会发生隐式转换转为布尔类型
if 单分支练习
用户输入成绩,如果成绩大于60,弹出”成绩合格“
双分支if语法:
if 多分支语法练习
用户输入,用户名:admin,密码:123456, 则提示登录成功,否则提示登录失
①:弹出输入框,分别输入用户名和密码
②:通过if语句判断,如果用户名是admin,并且密码是123456,则执行if里面的语句,否则执行else 里面的语句。
if 多分支语法练习2
让用户输入年份,判断这一年是闰年还是平年并弹出对应的警示框
分析:
①:能被4整除但不能被100整除,或者被400整除的年份是闰年,否则都是平年
②:需要逻辑运算
多分支if语法
使用场景: 适合于有多个结果的时候, 比如学习成绩可以分为: 优 良 中
- 先判断条件1,若满足条件1就执行代码1,其他不执行
- 若不满足则向下判断条件2,满足条件2执行代码2,其他不执行
- 若依然不满足继续往下判断,依次类推
- 若以上条件都不满足,执行else里的代码n
- 注:可以写N个条件,但这里演示只写2个
多分支if语法 案例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<script>
let num1= parseInt( prompt("请输入你的成绩"))
if(num1>=90){
alert("成绩优秀")
}else if(num1<90&&num1>=70){
alert("成绩良好")
}else if(num1<70&&num1>=60){
alert("成绩及格")
}else {
alert("成绩不合格或输入错误")
}
</script>
5.4 分支语句三元运算符
三元运算符是比if语句更加简洁的写法
使用场景
不想用if语句实现分支效果的时候,可以使用三元运算符
语法
? 与 : 配合使用
案例
1
2
3
4
5
6
7
8<script>
let num1= parseInt( prompt("请输入第一个数"))
let num2= parseInt( prompt("请输入第二个数"))
alert(num1>num2?'第一个数比较大':'第二个数 比较大')
</script>
5.5分支语句 switch
找到满足条件的值然后直接执行后续的语句
解释
找到跟小括号里数据全等的case值,并执行里面对应的代码
若没有全等 === 的则执行default里的代码
例:数据若跟值2全等,则执行代码2
注意
- switch case语句一般用于等值判断,不适合于区间判断
- switch case一般需要配合break关键字使用 没有break会造成case穿透
案例1
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<script>
let num1=parseInt(prompt("请输入第一个数"))
let num2=parseInt(prompt("请输入第二个数"))
let sp=prompt('请输入需要计算的方式+ - * /')
switch (sp) {
case '+':
alert(`${num1}+${num2}=${num1+num2}`)
break;
case '-':
alert(`${num1}-${num2}=${num1-num2}`)
break;
case '*':
alert(`${num1}*${num2}=${num1*num2}`)
break;
case '/':
alert(`${num1}/${num2}=${num1/num2}`)
break;
default:
alert("您可能输入错误")
break;
}
</script>
5.6while循环语句
循环就是重复的执行某一段代码
while : 在…. 期间, 所以 while循环 就是在满足条件期间,重复执行某些代码。
基本语法
解释
- 跟if语句很像,都要满足小括号里的条件为true才会进入 循环体 执行代码
- while大括号里代码执行完毕后不会跳出,而是继续回到小括号里判断条件是否满足,若满足又执行大括号里的代码,然后再回到小括号判断条件,直到括号内条件不满足,即跳出
while 循环三要素:
循环的本质就是以某个变量为起始值,然后不断产生变化量,慢慢靠近终止条件的过程。
所以,while循环需要具备三要素:
案例
使用while 语句在页面中打印出 10 句 “xxxxxxx”
1
2
3
4
5
6
7
8
9<script>
let i=0;
while(i<=9){
document.write(`xxxxxx<br>`)
i++
}
</script>while 练习
- 页面输入1-100
- 计算从1加到100 的和并输出
- 计算1-100 内的偶数和
1
2
3
4
5
6
7
8<script>
let i=1
while(i<=100){
document.write(`${i}<br>`)
i++
}
</script>1
2
3
4
5
6
7
8
9
10
11<script>
let i=1
let add=0
while(i<=100){
add+=i;
i++
}
document.write(add)
</script>1
2
3
4
5
6
7
8
9
10
11
12<script>
let i=1
let add=0
while(i<=100){
if(i%2==0){
add+=i
}
i++
}
document.write(add)
</script>
5.7 循环退出
循环不一定是执行完才退出,而是我们可以通过手动的形式退出
想要结束循环就需要使用两个关键字 continue 和break
break 退出整个循环
continue 结束本次循环继续下次循环
案例
1
2
3
4
5
6
7
8
9
10
11
12
13<script>
let i=0
while(i<10){
if(i===5){
break;
}
document.write(i)
i++
}
document.write("while 下面的代码")
</script>1
2
3
4
5
6
7
8
9
10let i=0
while(i<=10){
if(i===5){
i++ //如果这里没有i++: 因为contiune 会结束本轮循环也就是后面的代码都不执行,i 的值不发生改变,还是5,就会一直循环
continue
}
document.write(i)
i++
}练习
页面弹出对话框,”晚上吃什么?”,如果输入”螺蛳粉” 则结束循环,否则一直循环
1
2
3
4
5
6
7
8
9
10
11<script>
while(true){
let eat=prompt("晚上吃什么");
if(eat==='螺蛳粉4'){
break
}
}
alert("好")
</script>
5.8综合案例 ATM取款机
简易的ATM取款机操作,用户可以选择存钱,取钱,查看余额和退出的功能
思路分析
①:循环的时候,需要反复提示输入框,所以提示框写到循环里面
②:退出的条件是用户输入了 4,如果是4,则结束循环,不在弹窗
③:提前准备一个金额预先存储一个数额
④:取钱则是减法操作, 存钱则是加法操作,查看余额则是直接显示金额
⑤:输入不同的值,可以使用switch来执行不同的操作
实现
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<script>
//3. 准备一个变量来存放金额
let money = 0;//写在里面会重置
// 1. 循环, 一直询问用户 是存款还是啥,输入框写到循环里面
while (true) {
let cz = parseInt(
prompt(`
请选择你要进行的操作:
1.存钱
2.取钱
3.查看余额
4.退出
`)
)
// 2. 如果用户选择的退出的操作,那么就退出
if (cz == 4) {
alert("欢迎再次光临")
break
}
//4.根据输入做操作
switch (cz) {
// 存钱
// 将存的金额放到money 里面
case 1:
let cun = parseInt(prompt("请输入存款金额"))
money += cun
break;
// 取钱
// 从money 中减去取出的钱
case 2:
let qu = parseInt(prompt("请输入存款金额"))
money -= qu
break;
case 3:
alert(`您的金额是${money}`)
break
default:
break;
}
}
</script>
5.9循环语句for
作用重复执行代码
优点:把声明起始值、循环条件、变化值写到一起,让人一目了然,它是最常使用的循环形式
1
2
3
4//利用for循环输出三句话
for(let i=0;i<=3;i++){
alert("输出")
}for循环练习
1
2
3
4
5
6
7
8
9
10//打印数组
let arr=['关羽','张飞','赵云','马超','黄忠']
//打印数组
console.log(arr[0])
for(let i=0;i<5;i++){
document.write(arr[i])
}遍历数组(重点)
遍历数组就是从第一个循环到最后一个
1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
let arr = ['1', '2', '3', '4', '5']
for(let i=0;i<arr.length;i++){
alert(arr[i])
}
</script>
5.10 退出for循环
continue 退出本次循环,一般用于排除或者跳过某一个选项的时候, 可以使用continue
break 退出整个for循环,一般用于结果已经得到, 后续的循环不需要的时候可以使用
1
2
3
4
5
6
7
8//如果等于3的时候就退出本次循环
for (let i = 0; i < 4; i++) {
if(i===3){
continue// 退出本次循环,continue下面的代码就不在执行了,开启下一轮的循环
}
}1
2
3
4
5
6
7
for (let i = 0; i < 4; i++) {
if(i===3){
break //结束循环,执行执行训话下面的代码
}
}
5.11 for和whi le 循环的使用场景
- 当如果明确了循环的次数的时候推荐使用for循环
- 当不明确循环的次数的时候推荐使用while循环
5.12 for循环的嵌套
外面的循环嵌套内部的循环
嵌套for循环的执行顺序是,外面的for 的变量执行一次,然后里面的for变量执行,等里面的for循环执行完成了以后才会执行外面的for循环变量的改变
简单记忆: 外面循环执行一次,里面的循环执行所有次
案例
每一天记五个单词,三天记多少个单词
1
2
3
4
5
6
7
8
9
// 外层循环打印第几天
for (let i = 1; i<=3; i++) {
document.write(`第${i}`)
// 里层的for训话打印第几个单词
for (let j=1;j<=5;j++) {
document.write(`背第${j}个`)
}
}练习1 打印五行五列的 小星星
外层循环答应第几行,第几行,里层循环打印星星
1
2
3
4
5
6
7
8
9
10// 外层循环打印第几天
for (let i = 1; i<=5; i++) {
document.write(`<br>`)
// 里层的for训话打印第几个星星
for (let j=1;j<=5;j++) {
document.write("*")
}
}改进,通过用户的输入来打印对应的行数和列数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script>
let line=parseInt(prompt("请输入行数"))
let lie=parseInt(prompt("请输入列数"))
// 外层循环打印第几天
for (let i = 1; i<=line; i++) {
document.write(`<br>`)
// 里层的for训话打印第几个星星
for (let j=1;j<=lie;j++) {
document.write("*")
}
}
</script>练习2 打印直角三角形
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<script>
// 外面依旧是打印行数 每一行的星星数量和 行数是一样的
for(let i=1;i<=5;i++){
// 当行数是第一行的时候,只打印对应行数的星星
for(let j=1;j<=i;j++){
document.write(`*`)
}
document.write(`<br>`)
}
</script>九九乘法表
在倒三角的基础上试着进行改动,如把* 改成 1*1 看下效果
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>
<style>
span {
display: inline-block;
height: 30px;
width: 100px;
border:1px solid #19a543;
box-shadow: 3px 3px 3px rgba(0, 0, 0, .5);
text-align: center;
margin: 3px 3px;
}
</style>
<body>
<script>
// 外面依旧是打印行数 每一行的星星数量和 行数是一样的
for(let i=1;i<=9;i++){
// 当行数是第一行的时候,只打印对应行数的星星
for(let j=1;j<=i;j++){
document.write(`<span> ${i} X ${j} =${i*j}</span>`)
}
document.write(`<br>`)
}
</script>
</body>
</html>
5.13 数组的基本使用
数组:(Array)是一种可以按顺序保存数据的数据类型
思考:如果我想保存一个班里所有同学的姓名怎么办?
场景:如果有多个数据可以用数组保存起来,然后放到一个变量中,管理非常方便
数组的声明语法
使用构造函数的形式来声明数组(暂时做了解,后续构造函数会讲到)
数组是按顺序保存,所以每个数据都有自己的编号
计算机中的编号从0开始,所以小明的编号为0,小刚编号为1,以此类推
在数组中,数据的编号也叫索引或下标
数组可以存储任意类型的数据
数组的一些术语
元素:数组中保存的每个数据都叫数组元素
下标:数组中数据的编号
长度:数组中数据的个数,通过数组的length属性获得
数组遍历(重点)
数组练习
一个数组存储班上同学的成绩,求成绩的和 和平均值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<script>
// 需求: 求班上同学的成绩的总和及班上同学的平均成绩
let arr=[45,67,89,98,54]
// 声明一个sum 用来存放成绩的和
let sum=0;
for(let i=0;i<arr.length;i++){
sum+=arr[i]
}
let pjs=sum/arr.length
alert("班上成绩为"+sum)
alert("平均值为"+pjs)
</script>
求数组中的最大值和最小值
核心思路是打擂台: 用一个中间变量max,首先把数组中的第一个值赋值给max,依次和后面的变量进行比较,如果后面的值比max大,就把那个值给max。否则不做任何的操作。等所有的比较结束后,max中存放的就是最大 的那个值。
①:声明一个保存最大元素的变量 max。
②:默认最大值可以取数组中的第一个元素。
③:遍历这个数组,把里面每个数组元素和 max 相比较。
④:如果这个数组元素大于max 就把这个数组元素存到 max 里面,否则继续下一轮比较。
⑤:最后输出这个 max
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 <script>
let arr = [45, 67, 89, 98, 54]
let max=arr[0]
for(let i=0;i<arr.length;i++){
// 核心就是,依次比较,如果比max大就把值给max
if(max<arr[i]){
max=arr[i]
}
}
alert(max)
</script>
扩展练习: 输出一个数组中的 最大值 和 最小值
扩展二 使用 三元运算符来对求最大值和最小值进行改造
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 for(let i=0;i<arr.length;i++){
// 核心就是,依次比较,如果比max大就把值给max
// if(max<arr[i]){
// max=arr[i]
// }
max<arr[i]?max=arr[i]:max
// if(arr[i]<min){
// min=arr[i]
// }
min<arr[i]?min=arr[i]:min
}
5.14 操作数组
数组的操作主要是分为增删改查这些操作
更改数组中的元素
对数组中的元素进行重新赋值的操作
对数组中的元素进行赋值的操作
1
2let arr=[]
arr[0]=1更改数组中元素的值
1
2
3
4let arr=[1,2,3,4,5,6]
// 把下标为1的元素值更改为123
arr[1]=123一次性更改数组中的所有元素
1
2
3
4
5
6
7
8
9
10
11
12<script>
// 给每个元素后面都加一个老师
let techer=['张','李','王']
for(let i=0;i<techer.length;i++){
techer[i]= techer[i]+'老师'
}
for(let j=0;j<techer.length;j++){
alert(techer[j])
}
</script>向数组中添加新元素
push 推
数组.push() 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度 (重点)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
let arr=['2']
// 在数组的末尾添加三个元素 返回值是新的数组的长度
let arrLength= arr.push('2','3','3')
console.log(arr);
console.log(arrLength);
</script>arr.unshift(新增的内容) 方法将一个或多个元素添加到数组的开头,并返回该数组的新长度
1
2
3
4
5let arr2=['asdfa']
arr2.unshift('新添加的内容')
console.log(arr2);数组筛选案例:
需求:将数组 [2, 0, 6, 1, 77, 0, 52, 0, 25, 7] 中大于等于 10 的元素选出来,放入新数组
分析:
①:声明一个新的数组用于存放新数据newArr
②:遍历原来的旧数组, 找出大于等于 10 的元素
③:依次追加给新数组 newArr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<script>
let arr= [2, 0, 6, 1, 77, 0, 52, 0, 25, 7]
// 声明一个新的数组来存放筛选后得数据
let newArr=[]
// 遍历数组,拿到数组中的值
for(let i=0;i<arr.length;i++){
// 筛选,判断数组中的元素是否满足条件
if(arr[i]>10){
// 将满足条件的值添加到新数组中
newArr.push(arr[i])
}
}
console.log(newArr);
</script>案例: 数组去0 案例,将数组中的0都去除掉,形成一个不包含0 的数组
删除数组中的元素
数组. pop() 方法从数组中删除最后一个元素,并返回该元素的值
1
2
3let arr= [2, 0, 6, 1, 77, 0, 52, 0, 25, 7]
// 删除数组中的最后一个元素
arr.pop()数组. shift() 方法从数组中删除第一个元素,并返回该元素的值
1
2
3
4
5let arr= [2, 0, 6, 1, 77, 0, 52, 0, 25, 7]
// 删除数组中的第一个元素
arr.shift()
console.log(arr);数组. splice() 方法 删除指定元素
起始位置:开始删的位置,删除第几个
1
2
3
4
5let arr= [2, 0, 6, 1, 77, 0, 52, 0, 25, 7]
//从第二个开始删,删除三个
arr.splice(1,3)
console.log(arr);
5.15 综合案例,渲染柱状图
需求: 用户输入四个季度的数据,可以生成柱形图
分析:
①:需要输入4次,所以可以把4个数据放到一个数组里面
利用循环,弹出4次框,同时存到数组里面
②:遍历改数组,根据数据生成4个柱形图,渲染打印到页面中
柱形图就是div盒子,设置宽度固定,高度是用户输入的数据
div里面包含显示的数字和 第n季度
静态样式
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
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
width: 700px;
height: 300px;
background: rgba(0, 0, 0, 0.1);
border-left: 2px solid #000;
border-bottom:2px solid #000 ;
margin: 0 auto;
margin-top: 50px;
/* flex 布局 */
display: flex;
justify-content: space-around;
align-items: flex-end;
}
.box>div{
width: 50px;
display: flex;
flex-direction: column;
justify-content: space-between;
background-color: yellowgreen;
align-items: center;
}
.box div span{
margin-top: -20px;
}
.box div h4{
margin-bottom: -30px;
width: 70px;
margin-left: 10px;
}
</style>
</head>
<body>
<div class="box">
<div style="height: 130px;">
<span>123</span>
<h4>第一季度</h4>
</div>
<div style="height: 100px;">
<span>123</span>
<h4>第一季度</h4>
</div>
<div style="height: 100px;">
<span>123</span>
<h4>第一季度</h4>
</div>
<div style="height: 100px;">
<span>123</span>
<h4>第一季度</h4>
</div>
</div>
</body>
</html>四次弹窗效果
1
2
3
4
5
6
7
8
9// 1.四次弹框
// 声明一个数组用来存储用户输入的数据
let arr = []
for (let i = 1; i <= 4; i++) {
let num = prompt(`请输入第${i}季度的数据`)
// 将数据添加到数组中
arr.push(num)
}通过for循环把每个季度的盒子渲染出来
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 盒子开头
document.write(` <div class="box">`)
// 盒子中间使用循环来打印
for (let j = 0; j< arr.length; j++) {
document.write(`
<div style="height: ${arr[j]}px;">
<span>${arr[j]}</span>
<h4>第${arr[j]}季度</h4>
</div>
`)
}
// 盒子结尾
document.write(`</div>`)完整代码
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
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 700px;
height: 300px;
background: rgba(0, 0, 0, 0.1);
border-left: 2px solid #000;
border-bottom: 2px solid #000;
margin: 0 auto;
margin-top: 50px;
/* flex 布局 */
display: flex;
justify-content: space-around;
align-items: flex-end;
}
.box>div {
width: 50px;
display: flex;
flex-direction: column;
justify-content: space-between;
background-color: yellowgreen;
align-items: center;
}
.box div span {
margin-top: -20px;
}
.box div h4 {
margin-bottom: -30px;
width: 70px;
margin-left: 10px;
}
</style>
</head>
<body>
<script>
// 1.四次弹框
// 声明一个数组用来存储用户输入的数据
let arr = []
for (let i = 1; i <= 4; i++) {
let num = prompt(`请输入第${i}季度的数据`)
// 将数据添加到数组中
arr.push(num)
}
// 盒子开头
document.write(` <div class="box">`)
// 盒子中间使用循环来打印
for (let j = 0; j< arr.length; j++) {
document.write(`
<div style="height: ${arr[j]}px;">
<span>${arr[j]}</span>
<h4>第${j+1}季度</h4>
</div>
`)
}
// 盒子结尾
document.write(`</div>`)
</script>
</body>
</html>
6.函数
为什么要学习函数?
如果有好多地方都需要99乘法表,在其他的页面中也需要使用99乘法表,那么这个时候应该怎么办?
通过函数将代码抽取出来,在需要的地方进行调用就可以。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19// 函数的声明
function table99 () {
// 外面依旧是打印行数 每一行的星星数量和 行数是一样的
for (let i = 1; i <= 9; i++) {
// 当行数是第一行的时候,只打印对应行数的星星
for (let j = 1; j <= i; j++) {
document.write(`<span> ${i} X ${j} =${i * j}</span>`)
}
document.write(`<br>`)
}
}
// 函数的调用
table99()函数的概念
函数:
function,是被设计为执行特定任务的代码块
说明:
函数可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行这些被“包裹”的代码逻辑,这么做的优势是有利于
精简代码方便复用。
比如我们前面使用的 alert() 、 prompt() 和 console.log() 都是一些 js 函数,只不过已经封装好了,我们直接使用的
6.1函数的使用
函数的声明
1
2
3
4
5// 函数的声明
function sayHi(){
alert("你好")
}函数的调用
注意函数不调用是不会执行的,函数调用一次就使用一次,也就是说调用一次函数就会执行一次。
函数体
函数体是函数的构成部分,它负责将相同或相似代码“包裹”起来,直到函数调用时函数体内的代码才会被执行。函
数的功能代码都要写在函数体当中。
练习
函数案例
1
2
3
4
5
6function sum(){
let a=parseInt(prompt("请输入第一个数"))
let b=parseInt(prompt("请输入第一个数"))
document.write(`${a+b}`)
}
6.2函数传参
如果我想计算一个1-1000的和,我需要再重新的写一个函数吗?
解决办法:把要计算的数字传到函数内
若函数完成功能需要调用者传入数据,那么就需要用有参数的函数
这样可以极大提高函数的灵活性
函数参数的声明
根据用户传递的参数,来计算累加和
求1-x的累加和
1
2
3
4
5
6
7
8
9
10
11
function sum(end){
let add=0
for(let i=1;i<=end;i++){
add+=i
}
console.log(add);
}
//为函数传参
sum(30)求x-y的累加和
1
2
3
4
5
6
7
8
9
10function sum(start,end){
let add=0
for(let i=start;i<=end;i++){
add+=i
}
console.log(add);
}
//为函数传参
sum(100,200)形参与实参
形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)
实参:调用函数时写在函数名右边小括号里的叫实参(实际上的参数)
形参可以理解为是在这个函数内声明的变量(比如 num1 = 10)实参可以理解为是给这个变量赋值
开发中尽量保持形参和实参个数一致
我们曾经使用过的 alert(‘打印’), parseInt(‘11’), Number(‘11’) 本质上都是函数调用的传参
调用函数不传参数会怎么样
undefined
但是如果做用户不输入实参,刚才的案例,则出现 undefined + undefined 结果是什么?
NaN
1
2
3
4
5function Sum(a,b){
console.log(a+b);
}
Sum()//调用函数但是未传参参数默认值
我们可以改进下,用户不输入实参,可以给 形参默认值,可以默认为 0, 这样程序更严谨,可以如下操作:
1
2
3function Sum(a=0,b=0){
console.log(a+b);
}如果有参数就是用传递过来的参数,如果没有传递就使用默认值。
6.3函数案例
需求:学生的分数是一个数组,计算每个学生的总分
分析:
①: 封装一个求和函数
②: 传递过去的参数是一个数组
③: 函数内部遍历数组求和
1 | function arrSum(arr=[]){ |
用户输入x和y这两个数,写一个函数,使用这个函数来打印从x-y的和
1 | function sum(start,end){ |
6.4 函数的返回值
函数是被设计为执行特定任务的代码块
我们执行完成指定的任务后,把结果返回给调用者,如原材料送去加工,把加工的成品返回给我们
当调用某个函数,这个函数会返回一个结果出来,这就是有返回值的函数
函数返回值
当函数需要返回数据出去时,用return关键字
语法
return 返回的值是函数的调用者
1
2
3
4
5
6
7
8function fn(){
return 20
}
//相当于 fn()=20 也就是说把结果给了调用者fn()
//常写的形式
let a=fn()
//相当于 a=fn()=20案例
求和哈数
1
2
3
4
5function add(a=0,b=0){
return a+b
}
let numAdd=add(1,2)注意
- return 后面代码不会再被执行,会立即结束当前函数,所以 return 后面的数据不要写代码,return 后面的数据不要换行写
- 并不是所有的函数都需要返回值,没有return的函数默认是undefine
1
2
3
4
5
6function add(a=0,b=0){
return
a+b //不会执行
}
let numAdd=add(1,2)
1 | - 练习 |
1 | // 求最大数组的最大值 |
一次性求最大值和最小值
1 | // 求最大数组的最大值 |
6.5 函数细节补充
两个相同的函数后面的会覆盖前面的函数(不建议写两个函数名相同的函数)
在Javascript中 实参的个数和形参的个数可以不一致
如果形参过多 会自动填上undefined (了解即可)
如果实参过多 那么多余的实参会被忽略 (函数内部有一个arguments,里面装着所有的实参)
1
2
3
4
5function fun(a,b){
log(a,b)
}
fun(1,2,3) //剩余的实参不参与运算1
2
3
4
5function fun(a,c){ //如果虚参过多会自动填充undefind
log(a,c)
}
fun(1)函数一旦碰到return就不会在往下执行了 函数的结束用return
函数的返回值给了函数的调用者
break 和 return 的区别
return 结束的是函数
break 结束的是循环和switch ,也就是说他们作用不同
6.6函数的作用域
为什么会出现这种问题?
作用域概念
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
作用域分类
全局作用域是所有的地方都有效
局部作用域就是局部有效,在函数内部的就是局部作用域
1
2
3
4
5
6
7
8
9
10
11
12
13let num=0 //全局作用域
console.log(num);
function addNum(){
let a=0 //局部变量,在函数里面的就是局部变量
//局部变量就是只能在当前的函数里面使用的
return num+a
}
let add= addNum()在JavaScript中,根据作用域的不同,变量可以分为:
6.7 作用域的特殊情况
如果函数内部,变量没有声明,直接赋值,也当全局变量看,但是强烈不推荐
1 | function fn(){ |
但是有一种情况,函数内部的形参可以看做是局部变量。
1 | function fn(a=0){ //函数内部的形参可以看做局部变量 |
6.9作用域的冲突情况
在不同作用域下,可能存在变量命名冲突的情况,到底改执行谁呢?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15let num1=10
function fun(){
let num1=20;
function fun2(){
let num1=30
// 查找的时候先从当前的作用域找,接着一层一层王外面找
console.log(num1);
}
fun2()
}变量访问的规则
只要是代码,就至少有一个作用域
写在函数内部的局部作用域
如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域\
访问原则:在能够访问到的情况下 先局部, 局部没有在找全局
案例
结果是几
1
2
3
4
5
6
7
8
9function f1 () {
let num = 123
function f2 () {
console.log(num)
}
f2()
}
let num = 456
f1()结果是几
1
2
3
4
5
6
7
8
9
10function f1 () {
let num = 123
function f2 () {
let num = 0
console.log(num)
}
f2()
}
let num = 456
f1()结果是几
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16let a = 1
function fn1 () {
let a = 2
let b = '22'
fn2()
function fn2 () {
let a = 3
fn3()
function fn3 () {
let a = 4
console.log(a) //a的值 ?
console.log(b) //b的值 ?
}
}
}
fn1()
6.10 匿名函数
函数的分类
匿名函数概念
没有名字的函数,无法直接使用
函数表达式的使用
将匿名函数赋值给一个变量,并且通过变量名称进行调用 我们将这个称为函数表达式
1
2
3
4
5
6// 函数表达式
let fun=function(x,y){
alert(x+y)
}
// 函数表达式的调用
fun(1,3)其中函数的形参和实参使用跟具名函数一致。
函数表达式与具名函数的不同: 具名函数的调用可以放在任何位置,函数表达式,必须先声明后使用。
匿名函数
6.11 立即执行函数
使用场景: 避免全局变量之间的污染,在我们后面开发项目的时候,需要有很多个模块,模块之间的变量名有可能出现重复的情况,后面的变量名会把前面的变量名覆盖掉,造成变量之间的污染,所以我们可以采用立即执行函数
- 语法
1 | (function(){})(); |
声明多个立即执行函数:注意:一定要在最后面加分号
1 | (function(){ |
第一个小括号里面包裹的是一个函数,第二个小括号是调用前面的函数,所以立即执行函数在写完了就直接调用,本质上就是调用前面的函数。
1 | (function(x,y){ |
6.12时间转换案例
1 | <script> |
6.13逻辑中断
开发中,还会见到以下的写法:
1 | <script> |
- 短路:只存在于 && 和 || 中,当满足一定条件会让右边代码不执行
6.14 补充:隐式数据类型转换补充
转化为Boolean的类型的数据总结
- “” 空的字符串
- 0
- undefined
- null
- false
- NaN
以上的五个转化为Boolean类型都是false 其余的则为ture
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<script>
// Boolean() 方法可以将其他的数据类型转化为Boolean类型
console.log(Boolean(''));
console.log(Boolean(0));
console.log(Boolean(undefined));
console.log(Boolean(null));
console.log(Boolean(NaN));
console.log(Boolean(false));
console.log('----------------------------');
console.log(Boolean(-90));
console.log(Boolean(1));
console.log(Boolean('wyq'));
</script>转化为数字类型补充
- 有字符串的加法 “” + 1 ,结果是 “1”
- 减法 - (像大多数数学运算一样)只能用于数字,它会使空字符串 “” 转换为 0
- null 经过数字转换之后会变为 0
- undefined 经过数字转换之后会变为 NaN
1
2
3
4
5console.log(''-1); //-1
console.log('王英强'-1); //NaN
console.log(null+1); //0+1
console.log(undefined+1); //NaN
console.log(NaN+1); //NaN
7.对象
什么是对象 ,对象好用吗?
7.1 对象的概念
保存网站用户信息,比如姓名,年龄,电话号码… 用以前学的数据类型方便吗?
1 let people=[12,`张三`,'12334']
我们是不是需要学习一种新的数据类型,可以详细的描述某个事物?
对象的概念
对象(object):JavaScript里的一种数据类型
可以理解为是一种无序的数据集合, 注意数组是有序的数据集合
用来描述某个事物,例如描述一个人
人有姓名、年龄、性别等信息、还有吃饭睡觉打代码等功能
如果用多个变量保存则比较散,用对象比较统一比如描述 班主任 信息:
- 静态特征 (姓名, 年龄, 身高, 性别, 爱好) => 可以使用数字, 字符串, 数组, 布尔类型等表示
- 动态行为 (点名, 唱, 跳, rap) => 使用函数表示
对象的声明
1
let 对象名={}
1
let 对象名=new Object()
对象的使用
属性:信息或叫特征(名词)。 比如 手机尺寸、颜色、重量等…
方法:功能或叫行为(动词)。 比如 手机打电话、发短信、玩游戏…
1
2
3
4let 对象名={
属性名:属性值,
方法名:函数
}对象就是去描述这个事物
属性:
数据描述性的信息称为属性,如人的姓名、身高、年龄、性别等,一般是名词性的。
属性都是成 对出现的,包括属性名和值,它们之间使用英文 : 分隔
多个属性之间使用英文 , 分隔
属性就是依附在对象上的变量(外面是变量,对象内是属性)
属性名可以使用 “” 或 ‘’,一般情况下省略,除非名称遇到特殊符号如空格、中横线等
1
2
3
4
5let wangyingqiang={
name:"王英强",
age=39,
gender:'男'
}对象的属性之间没有顺序
案例(自己写)
7.2对象的使用
属性—查询
访问对象中的数据,访问数据中的属性和方法
获得对象中属性对应的值,称之为属性访问。
语法
对象.属性 或者 对象[ ‘ 属性名’ ](一定要把属性名用引号引起来)
简单理解就是获取对象中的属性值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15//对象的声明
let wangyingqiang={
name:"王英强",
age=39,
gender:'男'
}
//对象的属性
console.log(wangyingqiang.name)
console.log(wangyingqiang.age)
console.log(wangyingqiang.gender)
// 第二种方法
console.log(wangyingqiang['name']) //一定要加引号
属性–改
语法
1
语法:对象名.属性 = 新值
案例:将对象小红的性别改为男
1
2
3
4
5
6
7
8
9
10//对象的声明
let xiaohong={
name:"小红",
age=39,
gender:'男'
}
//更改对象的属性值
xiaohong.gender='女'
属性–改 增
如果有属性,重新赋值就是改
如果没有属性,赋值就是增加
1 | //对象的声明 |
属性–删(了解)
1 | //对象的声明 |
练习:
7.3 对象的方法
数据行为性的信息称为方法,如跑步、唱歌等,一般是动词性的,其本质是函数。
- 方法是由方法名和函数两部分构成,它们之间使用 : 分隔
- 多个属性之间使用英文 , 分隔
- 方法是依附在对象中的函数
- 方法名可以使用 “” 或 ‘’,一般情况下省略,除非名称遇到特殊符号如空格、中横线等
调用对象中的方法
声明对象,并添加了若干方法后,可以使用 . 调用对象中函数,称之为方法调用。
也可以添加实参和形参数
1
2
3
4
5
6
7
8
9
10
11let people={
name:"张三",
age:10,
sayHi:function(name){
alert(name+'你好')
}
}
people.sayHi('王五')练习:写一个对象person,有姓名性别,年龄这些属性。还有唱 跳 rap方法
7.4 遍历对象(重点)
for 遍历对象的问题:
对象没有像数组一样的length属性,所以无法确定长度
对象里面是无序的键值对, 没有规律. 不像数组里面有规律的下标
遍历对象
forin 遍历数组(能遍历数组 但是我们不推荐使用forin来遍历数组)
1
2
3
4
5let arr=[1,2,3,4]
for (let key in arr) { // key 在 arr 里面
console.log(key); //拿到的是数组的下标和索引 并且拿到的是字符串类型
}forin遍历对象(非常重要)
k 的值是字符串类型的, 所以使用obj.key 相当于是 obj.’userName’ 是获取不到对象中的属性的
但是使用 obj[‘属性名’] 这种形式就刚刚好
1
2
3
4
5
6
7
8
9
10
11// 遍历对象
for(let k in obj){
console.log(k); //k就是键值对的键名 也就是属性名 "userName" "age"
console.log(obj.k); //打印出来undefined 原因是 获取到的属性名是 'age'这种字符串类型
//也就是相当于 obj.'userName'
// 使用第二种写法
console.log(obj[k]); // obj['userName']
}一般不用这种方式遍历数组、主要是用来遍历对象
for in语法中的 k 是一个变量, 在循环的过程中依次代表对象的属性名
由于 k 是变量, 所以必须使用 [ ] 语法解析
一定记住: k 是获得对象的属性名, 对象名[k] 是获得 属性值
遍历对象使用哪个语句?
for in
遍历对象中, for k in obj,获得对象属性是那个,获得值是那个?
获得对象属性是 k
获得对象值是 obj[k]
7.5 遍历数组对象
需求: 请把下面数据中的对象打印出来:
1 | // 定义一个存储了若干学生信息的数组 |
1 | <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
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
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
table {
width: 600px;
text-align: center;
}
table,
th,
td {
border: 1px solid #ccc;
border-collapse: collapse;
}
caption {
font-size: 18px;
margin-bottom: 10px;
font-weight: 700;
}
tr {
height: 40px;
cursor: pointer;
}
table tr:nth-child(1) {
background-color: #ddd;
}
table tr:not(:first-child):hover {
background-color: #eee;
}
</style>
</head>
<body>
<h2>学生信息</h2>
<p>将数据渲染到页面中...</p>
<table>
<caption>学生列表</caption>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>家乡</th>
</tr>
<tr>
<td>1</td>
<td>小明</td>
<td>18</td>
<td>男</td>
<td>河北省</td>
</tr>
<tr>
<td>1</td>
<td>小明</td>
<td>18</td>
<td>男</td>
<td>河北省</td>
</tr>
<tr>
<td>1</td>
<td>小明</td>
<td>18</td>
<td>男</td>
<td>河北省</td>
</tr>
<tr>
<td>1</td>
<td>小明</td>
<td>18</td>
<td>男</td>
<td>河北省</td>
</tr>
<tr>
<td>1</td>
<td>小明</td>
<td>18</td>
<td>男</td>
<td>河北省</td>
</tr>
<tr>
<td>1</td>
<td>小明</td>
<td>18</td>
<td>男</td>
<td>河北省</td>
</tr>
</table>
</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<script>
// 数据准备
let students = [
{ name: '小明', age: 18, gender: '男', hometown: '河北省' },
{ name: '小红', age: 19, gender: '女', hometown: '河南省' },
{ name: '小刚', age: 17, gender: '男', hometown: '山西省' },
{ name: '小丽', age: 18, gender: '女', hometown: '山东省' }
]
// 渲染页面
document.write(`
<table>
<caption>学生列表</caption>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>家乡</th>
</tr>`)
for (let i = 0; i < students.length; i++) {
document.write(
`
<tr>
<td>${i + 1}</td>
<td>${students[i].name}</td>
<td>18</td>
<td>男</td>
<td>河北省</td>
</tr>
`
)
}
document.write(`
</table>
`)
</script>
7.6内置对象
JavaScript内部提供的对象,包含各种属性和方法给开发者调用
比如说手机很多功能都是手机厂商给我们开发好了,我们直接使用就可以
document.write() document就是我们最常用的对象
console.log() console 也是内置的对象
数学对象Math
介绍:Math对象是JavaScript提供的一个“数学”对象
作用:提供了一系列做数学运算的方法
Math对象包含的方法有:
random:生成0-1之间的随机数(包含0不包括1)
ceil:向上取整
floor:向下取整
max:找最大数
min:找最小数
pow:幂运算
abs:绝对值
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<script>
// 向上取整
console.log(Math.ceil(1.9));
console.log(Math.ceil(1.1));
// 向下取整
console.log(Math.floor(1.2));
console.log(Math.floor(1.9));
// 四舍五入
console.log(Math.round(1.9));
console.log(Math.round(1.2));
console.log(Math.round(-1.5)); // -1
console.log(Math.round(-20.51)); // -21
//最大值
console.log(Math.max(1,2,3,4,5,6))
// 求最小值
console.log(Math.min(1,3,4,9));
// 绝对值
console.log(Math.abs(-1));
</script>内置对象-生成随机数
Math.random() 随机数函数, 返回一个0 - 1之间,并且包括0不包括1的随机小数 [0, 1)
生成0-10 之间的随机数
1
2
3Math.floor(Math.random()*(10+1))
//Math.random()*(10+1) 是取的0-11 包含0 不包含11 的随机数
//Math.floor() 向下取整,最大值只能是10 例如10.99 向下取整为10生成0-10之间的随机数(0的概率极少)
1
2Math.ceil(Math.random()*10)
//Math.ceil() 向上取整 9.1 取整为10生成0-10之间的随机数(round四舍五入,即生成0-10的随机整数数,取0和10的概率是其他数的一半)
1
2Math.round(Math.random()*10)
//如 1.2 为1 1.6 为2通过随机数取数组中的一个随机的元素(重要)
1
2
3
4
5
6
7
8
9let arr =['张三','李四','王五']
let random = Math.floor(Math.random()*3) //能取0-2 之间的随机数
//通过几次实验可以发现 random 后面乘于的那个数字 和数组的长度是一样的
// 为了避免重复更改,所以我们将写死的数据改成数组的长度
let random=Math.floor(Math.random()*arr.length)
console.log(arr[random]);生成N-M 之间的随机数(不理解就背,或者直接翻到这个位置抄一遍)
1
Math.floor( Math.random()*(M-N+1) )+N
封装一个N-M的随机数的函数
1
2
3
4
5
6
7
8
9
10<script>
function getRandom(N,M){
return Math.floor( Math.random()*(M-N+1) )+N
}
let a=getRandom(1,100)
console.log(a);
</script>
7.7 案例-随机点名
需求:请把 [‘赵云’, ‘黄忠’, ‘关羽’, ‘张飞’, ‘马超’, ‘刘备’, ‘曹操’] 随机显示一个名字到页面中
分析
①:利用随机函数随机生成一个数字作为索引号
②: 数组[随机数] 生成到页面中
实现
最基础的随机数
1
2
3
4
5
6
7
8
9
10
11<script>
let arr=['a','b','v','c']
// 得到一个随机数,作为十足的索引号
let random=Math.floor(Math.random()*arr.length)
// 把这个随机数作为数组下标输出到页面上
document.write(`${arr[random]}`)
</script>改进: 请把 [‘赵云’, ‘黄忠’, ‘关羽’, ‘张飞’, ‘马超’, ‘刘备’, ‘曹操’] 随机显示一个名字到页面中,但是不允许重复显示
①:利用随机函数随机生成一个数字作为索引号
②:数组[随机数] 生成到页面中
③:数组中删除刚才抽中的索引号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<script>
let arr=['a','b','v','c']
// 得到一个随机数,作为十足的索引号
let random=Math.floor(Math.random()*arr.length)
// 把这个随机数作为数组下标输出到页面上
document.write(`${arr[random]}`)
//通过splice 将以及抽中的元素删除掉
//splice(删除的位置,删除几个) random 是以及选中的,删除这一个
arr.splice(random,1)
</script>
猜数字游戏
需求:程序随机生成 1~10 之间的一个数字,用户输入一个数字
分析
①:如果大于该数字,就提示,数字猜大了,继续猜
②:如果小于该数字,就提示,数字猜小了,继续猜
③:如果猜对了,就提示猜对了,程序结束
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<script>
//1. s随机生成一个数字
//2. 用户输入一个值
// 3.判断输出
function getRandom (N, M) {
return Math.floor(Math.random() * (M - N + 1) + N
}
// 获取一个随机数
let random = getRandom(1, 10)
while (true) {
// 获取用户的输入
let num = parseInt(prompt("请输入一个数"))
// 判断
if (num > random) {
alert('猜大了')
}
if (num < random) {
alert('猜小了')
}
if (num ===random) {
alert("猜对了")
break
}
}
</script>猜数字游戏–设定次数
基础版 —无提示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<script>
function getRandom (N, M) {
return Math.floor(Math.random() * (M - N + 1)) + N
}
// 获取一个随机数
let random = getRandom(1, 10)
let flog = true
for (let i = 1; i <= 3; i++) {
let num = parseInt(prompt("请输入一个数"))
if (num > random) {
alert("猜大了")
} else if (num < random) {
alert("猜小了")
} else {
alert('猜对了')
break
}
}
</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<script>
function getRandom (N, M) {
return Math.floor(Math.random() * (M - N+ 1) ) + N
}
// 获取一个随机数
let random = getRandom(1, 10)
// 设置一个开关,用来提示次数是否用完了
let flog = true
for (let i = 1; i <= 3; i++) {
let num = parseInt(prompt("请输入一个数"))
if (num > random) {
alert("猜大了")
} else if (num < random) {
alert("猜小了")
} else {
// 如果猜对了,就不提示次数用完了
flog=false
alert('猜对了')
break
}
}
if(flog){
alert('次数用完了')
}
</script>
7.8 案例-在线商城案例
1 | <!DOCTYPE html> |
7.9JavaScript基础总结及扩展
术语解释
基础数据类型和引用数据类型
简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型。
- 值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型
string ,number,boolean,undefined,null
- 引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型
通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等
堆栈空间的区别
1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的
栈;
简单数据类型存放到栈里面
2、堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
*引用数据类型存放到堆里面
数据类型的存储
1
2
3
4
5
6
7
8
9
10
11
12
13
14let num1=10
let num2=num1
num2=20
log(num1)//?
//--------------------------------------
let obj1={ age:10 }
let obj2=obj1
obj2.age=30
log(obj1.age )
学到这里你已经掌握了JavaScript的基础的语法了。能写一些简单的案例,已经相当棒了。像变量,函数,循环,数据类型,对象等等。剩下的时间需要我们学习webApi主要的内容为:
- DOM获取元素,获取页面中的元素。
- DOM-事件,注册事件、tab栏切换
- 事件对象,事件委托
- DOM节点操作
- BOM浏览器操作
- 正则表达式
- js项目实战
8.webAPI–DOM对象
8.1声明变量const 优先
建议: const 优先,尽量使用const,
原因是:const 语义化更好
很多变量我们声明的时候就知道他不会被更改了,那为什么不用 const呢?
有变量先使用const 如果发现他后面被修改在改为let
下面代码的let可以改为const吗?
1 | let arr =[1,2,3,4,5] |
可以: 原因是复杂数据类型是栈里面存放的是地址,数据是存放在堆里面的。修改的话只是改变堆里面的数据,栈里面地址并没有发生改变,也就是说存储的值并没有发生改变。
1 | let arr=[1,2,4,5] |
以上的情况是不行的,原因是给了变量一个新的数组,那么就是相当于开辟了一个新的地址(新的数组开辟新的地址),所以说这种情况是不行的。
- 什么时候使用const 什么时候使用let
为什么const声明的对象可以修改里面的属性?
因为对象是引用类型,里面存储的是地址,只要地址不变,就不会报错
建议数组和对象使用 const 来声明
什么时候使用let声明变量?
如果基本数据类型的值或者引用类型的地址发生变化的时候,需要用let
比如 一个变量进行加减运算,比如 for循环中的 i++
8.2 API的作用和分类–DOM
作用: 就是使用 JS 去操作 html 和浏览器
分类:DOM (文档对象模型)、BOM(浏览器对象模型)
简单来说就是可以通过js来控制页面中的元素,放大缩小,点击以后产生效果等等。
DOM
DOM(Document Object Model——文档对象模型)是用来呈现以及与任意 HTML 或 XML文档交互的API
白话:DOM是浏览器提供的一套专门用来 操作网页内容 的功能
例如:通过js来操作网页里面的内容
DOM树
将 HTML 文档以树状结构直观的表现出来,我们称之为文档树或 DOM 树
描述网页内容关系的名词WWWWW
作用:文档树直观的体现了标签与标签之间的关系
DOM对象(重要)
浏览器根据html标签生成的 JS对象
- 所有的标签属性都可以在这个对象上面找到,(所有的标签拿到之后都是以对象的形式展现的,只要是对象都会有属性和方法 )
- 修改这个对象的属性会自动映射到标签身上
div 获取过来的就是对象
1
2
3
4<script>
let box=document.querySelector('div')
console.dir(box);
</script>DOM的核心思想
把网页内容当做对象来处理
document 对象
是 DOM 里提供的一个对象
所以它提供的属性和方法都是用来访问和操作网页内容的
document.write()
网页所有内容都在document里面
8.3获取DOM对象
根据CSS选择器来获取DOM元素 (重点)
其他获取DOM元素方法(了解)
提问:我们想要操作某个标签首先做什么?
肯定首先选中这个标签,跟 CSS选择器类似,选中标签才能操作
查找元素DOM元素就是利用 JS 选择页面中标签元素
(1) document.querySelector (query 查询,selecotor 选择器)
作用:选择匹配的第一个元素, 它的返回值是第一个元素对象
css选择器怎么写,js就怎么写
如果没有找到就返回null
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<body>
<div class="box">aaa</div>
<div id="box">我是box</div>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
<script>
// 获取第一个元素
// 通过标签名
document.querySelector('div')
// 通过类名
document.querySelector('.box')
//通过id
document.querySelector('#box')
//获取第一个li
document.querySelector('ul li:first-child')
</script>
</body>document.querySelectorAll( css 选择器)
选择匹配的多个元素
返回给我们的是一个数组,如果我们想要修改其中的元素,我们就需要使用数组遍历
得到的是一个伪数组,能获取到数组的长度,但是没有办法使用push pop等数组方法
哪怕是只有一个元素,返回给我们的也是伪数组
1
2//获取所有的li
document.querySelectorAll('li')练习
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<body>
<ul class="nav">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
// 获取li
let lis=document.querySelectorAll('.nav li')
for(let i=0;i<lis.length;i++){
console.log(lis[i]);
}
</script>
</body>总结
. 获取页面中的标签我们最终常用那两种方式?
- querySelectorAll()
- querySelector()
他们两者的区别是什么?
querySelector() 只能选择一个元素, 可以直接操作
querySelectorAll() 可以选择多个元素,得到的是伪数组,需要遍历得
到每一个元素
他们两者小括号里面的参数有什么注意事项?
- 里面写css选择器
- 必须是字符串,也就是必须要加引号
其他获取DOM元素的方法(了解,以前使用,现在慢慢被淘汰)
8.4操作元素的内容
目标是能欧修改元素里面的文本内容
DOM对象都是根据标签生成的,所以操作标签,本质上就是操作DOM对象。
就是操作对象使用的点语法。
如果想要修改标签元素的里面的内容,则可以使用如下几种方式:
- 对象.innerText 属性
- 对象.innerHTML 属性
元素innerText 属性
将文本内容添加/更新到任意标签位置
显示纯文本,不解析标签
1
2
3
4
5
6
7
8
9
10
11
12<script>
// 获取元素
const box=document.querySelector('.box')
console.dir(box);
// 修改标签文字内容
box.innerText="修改后的文字内容"
//
</script>元素.innerHTML 属性
将文本内容添加/更新到任意标签位置
会解析标签,多标签建议使用模板字符
1
2
3
4
5
6
7
8
9
10
11
12<script>
// 获取元素
const box=document.querySelector('.box')
console.dir(box);
//修改标签
box.innerHTML=`<h1>我是修改后的内容</h1>`
</script>元素.innerHTML 属性 能识别文本,能够解析标签
如果还在纠结到底用谁,你可以选择innerHTML
案例
需求:从数组随机抽取一等奖、二等奖和三等奖,显示到对应的标签里面。
静态文件素材
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>年会抽奖</title>
<style>
.wrapper {
width: 840px;
height: 420px;
background: url(./images/bg01.jpg) no-repeat center / cover;
padding: 100px 250px;
box-sizing: border-box;
}
</style>
</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>
</script>
</body>
</html>①:声明数组: const personArr = [‘周杰伦’, ‘刘德华’, ‘周星驰’, ‘王老师’, ‘张学友’]
②:一等奖:随机生成一个数字(0~数组长度),找到对应数组的名字
③:通过innerText 或者 innerHTML 将名字写入span元素内部
④: 二等奖依次类推
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<!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 {
width: 840px;
height: 420px;
background: rgb(223, 10, 10);
padding: 100px 250px;
box-sizing: border-box;
}
</style>
</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 personArr = ['周杰伦', '刘德华', '周星驰', '王老师', '张学友']
// 生成一个数组的是随机下标
const random=Math.floor(Math.random()*personArr.length)
// 将获取到到的元素通过innerhHtml添加到html元素中
// 1.获取元素
const one=document.querySelector('#one')
//2.将选中的数组元素渲染到页面中
one.innerHTML=personArr[random]
// 3.从数组中删除已经选中的元素
personArr.splice(random,1)
// 4.二等奖和三等奖是一样的原理
// 生成一个数组的是随机下标
const random2=Math.floor(Math.random()*personArr.length)
// 将获取到到的元素通过innerhHtml添加到html元素中
// 1.获取元素
const two=document.querySelector('#two')
//2.将选中的数组元素渲染到页面中
two.innerHTML=personArr[random]
// 3.从数组中删除已经选中的元素
personArr.splice(random2,1)
</script>
</body>
</html>
8.5 修改元素的属性
操作元素常用属性
操作元素样式属性
操作 表单元素 属性
可以通过 JS 设置/修改标签元素属性,比如通过 src更换 图片
最常见的属性比如: href、title、src 等
语法
对象.属性=值
修改图片对象的属性
1
2
3
4
5
6
7
8
9
10
11
12
13<body>
<img src="/img/js/jpg" alt="我是照片" class="img">
<script>
// 获取元素
const img=document.querySelector('.img')
// 修改img的属性值
img.scr="/img/js2.jpg"
</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<body>
<img src="./1.jpg" alt="" class="img">
<script>
// 获取img对象
const img = document.querySelector('.img')
// 生成一个1-2之间的随机数
function getRandom (N, M) {
return Math.floor(Math.random() * (M - N + 1) + N)
}
let num=getRandom(1,2)
// 更改对象中的scr属性
img.src=`./${num}.jpg`
</script>
</body>
8.6操作样式属性
- 通过 style 属性操作CSS
- 操作类名(className) 操作CSS
- 通过 classList 操作类控制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<body>
<div class="box">我是box</div>
<script>
//获取元素
const box =document.querySelector('.box')
//通过 对象.style=值
box.style.width='200px'
box.style. backgroundColor='yellow'
box.style. border='1px solid #ccc'
</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<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
background: url(./1.jpg) no-repeat top center;
}
</style>
</head>
<body>
<script>
// 生成一个1-2之间的随机数
function getRandom (N, M) {
return Math.floor(Math.random() * (M - N + 1) + N)
}
let random=getRandom(1,2)
document.body.style.background=`url(./${random}.jpg) no-repeat top center`
</script>
</body>
</html>
8.7通过类名修改样式
通过给元素添加class或者修改元素的class 实现一下子切换元素样式的效果
语法:
元素对象.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
42<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
width: 100px;
height: 100px;
background-color: red;
}
.box{
width: 200px;
height: 200px;
background-color: yellowgreen;
}
.border{
border: 2px solid #333333;
}
</style>
</head>
<body>
<div></div>
<script>
// 获取元素
let divBox=document.querySelector('div')
// 添加类名 添加一个class类名
divBox.className='box'
//一次添加多个类名
divBox.className='box border'
</script>
</body>
</html>注意
- 由于class是关键字, 所以使用className去代替
- className是使用新值换旧值, 如果需要添加一个类,需要保留之前的类名
8.8通过classlist 的方法来追加和删除类名
为了解决className 容易覆盖以前的类名,我们可以通过classList方式追加和删除类名
语法
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<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box{
width: 100px;
height: 100px;
background-color: red;
}
.color{
color: yellow;
}
.mt{
margin-top: 300px;
}
</style>
</head>
<body>
<div class="box">我是box</div>
<script>
//通过classlist添加类名
// 1.获取元素
const box=document.querySelector('.box')
// 2.修改样式
// 添加类
box.classList.add('color') //类名不加点
// 删除类
box.classList.remove('color')
//切换类 toggle() 没有类就加上 有类就替换
box.classList.toggle('mt')
</script>
</body>
</html>className和classList的区别
- 修改大量样式的更方便
- 修改不多样式的时候方便
- classList 是追加和删除不影响以前类名
8.9 综合案例 随机轮播图
页面一刷新就随机的换一张图片,切换一个小点,同时换一个标题
整体思路
- 首先看结构, css 样式不用管他。
- 小圆点,图片,标题是否都是同一个对象中的内容。
- 是否要生成一个随机数, 将对应的对象选渲染到页面上。
详细思路
分析:
①: 准备一个数组对象,里面包含详细信息(素材包含)
②: 随机选择一个数字,选出数组对应的对象,更换图片,底部盒子背景颜色,以及文字内容
③: 利用这个随机数字,让小圆点添加高亮的类(addClass) 利用css 结构伪类选择器
1 |
|
8.10 操作表单元素属性
文本框,单选按钮,多选按钮
获取表单值 修改表单内容
表单.value
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<body>
<input type="text" valid="电脑">
<script>
// 获取元素
const name=document.querySelector('input')
// 获取表单里面的值 表单.value
console.log(name.value)
// 修改表单中的值
name.value="我要买电脑"
// 修改表单属性
name.type='password'
name.type='text'
</script>
</body>修改表单属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<body>
<input type="checkbox" checked>
<script>
// 获取元素
const name=document.querySelector('input')
// 获取表单里面的值 表单.value
console.log(name.checked)
// 勾选
name.checked=true
</script>
</body>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<body>
<button disabled>点击</button>
<script>
// 获取元素
const name=document.querySelector('button')
// 获取表单里面的值 表单.value
console.log(name.disabled)
// 勾选
name.disabled=false
</script>
</body>8.11 自定义属性
标准属性: 标签天生自带的属性 比如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<body>
<!-- 自定义属性 -->
<div data- id="1" data-age="不知道"></div>
<div data- id="1"></div>
<div data- id="1"></div>
<div data- id="1"></div>
<div data- id="1"></div>
<script>
const one=document.querySelector('div')
// 获取自定义属性
console.log(one.dataset);
</script>
</body>
8.11 间隙函数–定时器
- 开启定时器
1 | <script> |
注意:调用函数的时候不需要加()
1 | <script> |
定时器返回的是一个数字,也就是当前定时器的编号
1 | // 定时器的返回值是一个编号 |
关闭定时器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<script>
function fun(){
// console.log('执行');
}
// 定时器的返回值是一个编号
let num= setInterval(fun,1000)
console.log(num);
// 关闭定时器
clearInterval(num)
</script>
8.12 综合案例
每隔一秒切换一张照片
1 | <!DOCTYPE html> |
9.事件
9.1 事件监听
什么是事件?
事件是在编程时系统内发生的动作或者发生的事情,比如用户在网页上单击一个按钮
什么是事件监听?
就是让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称为 绑定事件或者注册事件
比如鼠标经过显示下拉菜单,比如点击可以播放轮播图等等
事件监听语法
事件监听三要素
事件源: 那个dom元素被事件触发了,要获取dom元素(谁被触发了)
事件类型: 用什么方式触发,比如鼠标单击 click、鼠标经过 mouseover 等(什么方式触发)
事件调用的函数: 要做什么事(要做什么)
点击按钮 ,弹出对话框
事件源:哪个DOM对象被监听了?(谁)
事件类型: 用什么方式触发,如单击鼠标,鼠标经过等。(什么方式)
事件处理程序: 弹出对话框 (什么反应)
1
2
3
4
5
6
7
8
9
10<body>
<button>点击</button>
<script>
let btn=document.querySelector('button')
//click 鼠标点击事件
btn.addEventListener('click',function(){
alert("弹出")
}) //点击一次就触发一次
</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<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
height: 300px;
width: 300px;
margin: 0 auto;
background-color: red;
display: flex;
justify-content: end;
align-items: start;
}
button{
}
</style>
</head>
<body>
<div>
<button>点击</button>
</div>
<script>
let btn=document.querySelector('button')
let box=document.querySelector('div')
btn.addEventListener('click',function(){
box.style.display='none'
})
</script>
</body>
</html>
9.2事件监听版本
DOM L1.0
事件源.on事件 = function() { }
会出现事件覆盖的情况
1
2
3
4
5
6
7
8let btn=document.querySelector('button')
btn.onclick=function(){
alert("1111")
}
btn.onclick=function(){
alert('ddd')
DOM L2.0
事件源.addEventListener(事件, 事件处理函数)
1
2
3btn.addEventListener('click',function(){
alert("ddd")
})区别:
on方式会被覆盖,addEventListener方式可绑定多次,拥有事件更多特性,推荐使用
发展史
DOM L0 :是 DOM 的发展的第一个版本; L:level
DOM L1:DOM级别1 于1998年10月1日成为W3C推荐标准
DOM L2:使用addEventListener注册事件
DOM L3: DOM3级事件模块在DOM2级事件的基础上重新定义了这些事件,也添加了一些新事件类型
9.3 事件类型
鼠标移入和鼠标离开
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 name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
height: 300px;
width: 300px;
margin: 0 auto;
background-color: yellowgreen;
}
.box{
height: 100px;
width: 200px;
margin: 0 auto;
background-color: rgb(201, 233, 137);
}
</style>
</head>
<body>
<div></div>
<script>
let box=document.querySelector("div")
// 鼠标移入事件
box.addEventListener('mouseenter',function(){
box.classList.add("box")
})
// 鼠标离开事件
box.addEventListener('mouseleave',function(){
box.classList.remove('box')
})
</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
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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250<!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;
margin: 0 auto;
margin-top: 100px;
}
.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 中包含的是n个小圆点 -->
<ul class="slider-indicator">
<!-- active 是给圆点加上高亮的效果 -->
<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>
// 1. 初始数据(数组对象 数组中用多个对象)
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)' },
]
// 获取对应的标签元素
// 图片
let img = document.querySelector('.slider-wrapper img')
// p标签
let p = document.querySelector('.slider-footer p')
// 切换颜色的div
let color = document.querySelector('.slider-footer')
// 上个的箭头
let prev = document.querySelector(".prev")
// 下一个的箭头
let next = document.querySelector(".next")
// 大盒子
let bigBox=document.querySelector(".slider")
let i = 0 //第几章照片
// 注册点击事件 下一张照片
next.addEventListener('click', function () {
// 切换下一张照片 标题 背景都要换
i++
// 如果大于8 就复原
if (i >= Data.length) {
i = 0
}
// i>=Data.length?0:i
img.src = Data[i].url
p.innerHTML = Data[i].title
color.style.backgroundColor = Data[i].color
// 移除旧的小圆点
document.querySelector('.slider-indicator .active').classList.remove('active')
// 当前的li添加小圆点的类
document.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')
})
// 注册点击事件 上一张照片
prev.addEventListener('click', function () {
// 切换下一张照片 标题 背景都要换
i--
// 如果大于8 就复原
if (i <0) {
// 最后一张照片的索引
i = 7
}
// i>=Data.length?0:i
img.src = Data[i].url
p.innerHTML = Data[i].title
color.style.backgroundColor = Data[i].color
// 移除旧的小圆点
document.querySelector('.slider-indicator .active').classList.remove('active')
// 当前的li添加小圆点的类
document.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')
})
// 定时器自动播放
let id= setInterval(function(){
// js自动调用事件 next 这个DOM对象自动调用点击事件
next.click()
}, 100);
// 鼠标经过大盒子的时候关闭定时器
bigBox.addEventListener('mouseenter',function(){
// 关闭定时器
clearInterval(id)
})
// 鼠标离开大盒子,开启定时器
bigBox.addEventListener('mouseleave',function(){
// 停止之前的定时器
clearInterval(id)
// 开启一个定时器,把定时器的编号给id,下次关的时候是同一个定时器
id=setInterval(function(){
// js自动调用事件 next 这个DOM对象自动调用点击事件
next.click()
}, 100);
})
// setInterval(function () {
// i++
// // 无缝衔接的位置
// if (i >= Data.length) {
// i = 0
// }
// img.src = Data[i].url
// p.innerHTML = Data[i].title
// color.style.backgroundColor = Data[i].color
// document.querySelector('.slider-indicator .active').classList.remove('active')
// // 这样的话会给每一li添加样式
// document.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')
// }, 10000)
</script>
</body>
</html>
9.4 焦点事件
一般都是适用于表单中的input框
focus 获得焦点
blur 失去焦点
1 | <!DOCTYPE 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<!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 {
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>
// 获取对应的元素
let input=document.querySelector('input')
let 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.rem('search')
})
</script>
</body>
</html>
9.5 键盘事件
keydown 键盘按下事件
keyup 键盘抬起事件
1 | <body> |
9.6输入事件
只要用户输入内容就会触发对应的事件
想要获取用户的输入内容可以使用对象.value来获取
1 | <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
143
144
145
146<!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>
let tx=document.querySelector('#tx')
let total=document.querySelector('.total')
// 1. 当文本获取了焦点以后,就让p标签显示出来
tx.addEventListener('focus',function(){
// 通过控制透明度
total.style.opacity=1
})
// 2.当失去焦点的时候,就让p标签隐藏起来
tx.addEventListener('blur',function(){
// 通过控制透明度
total.style.opacity=0
})
// 3.检测用户输入的值及用户输入的长度
tx.addEventListener('input',function(){
// 获取用户输入的长度 tx.value.length
total.innerHTML=`${tx.value.length}/200`
})
</script>
</body>
</html>
9.7事件对象
事件对象是什么
也是个对象,这个对象里有事件触发时的相关信息
例如:鼠标点击事件中,事件对象就存了鼠标点在哪个位置等信息
l使用场景
可以判断用户按下哪个键,比如按下回车键可以发布新闻
可以判断鼠标点击了哪个元素,从而做相应的操作
获取事件对象
在事件绑定的回调函数的第一个参数就是事件对象
一般命名为event、ev、e
1 | <script> |
9.8事件对象的常用属性
部分常用属性
type
获取当前的事件类型
clientX/clientY
获取光标相对于浏览器可见窗口左上角的位置
offsetX/offsetY
获取光标相对于当前DOM元素左上角的位置
key
用户按下的键盘键的值 keyCode(目前不适用)
1 | <body> |
案例:按下回车,发布评论
①:用到按下键盘事件 keydown 或者 keyup 都可以
②:如果用户按下的是回车键盘,则发布信息
③:让留言信息模块显示,把拿到的数据渲染到对应标签内部
1 | <!DOCTYPE html> |
9.9环境对象
指的是函数内部特殊的变量 this ,它代表着当前函数运行时所处的环境
- 每个函数都有this环境对象,普通函数中的this指向window
1 | <script> |
谁调用, this 就是谁 是判断 this 指向的粗略规则
粗略的记,谁调用函数,this就指向谁
1 | <body> |
如果我们想要改变按钮的颜色,前后的两种写法
1 | <body> |
9.10回调函数
如果将函数 A 做为参数传递给函数 B 时,我们称函数 A 为回调函数
简单理解: 当一个函数当做参数来传递给另外一个函数的时候,这个函数就是回调函数
例如,定时器, 隔一秒回过头来调用这个函数就叫做回调函数
事件监听函数:当点击按钮或者什么时候调用这个函数
9.11 Tab切换
- 分析:
①:主要核心是类的切换, 设定一个当前类,可以让当前元素高亮
②:鼠标经过当前选项卡,先移除其余元素身上的当前类,而只给当前元素添加类,
③:注意,当前类只能有一个
1 | <!DOCTYPE html> |
9.12 事件流(DOM 高级)
事件流指的是事件完整执行过程中的流动路径
例如:要来襄阳找我学挖掘机,首先到中国,到湖北,到襄阳,到湖北文理学院理工学院这是事件的捕获,冒泡就是从里到外
9.13事件捕获
从DOM的根元素开始去执行对应的事件 (从外到里)
事件捕获需要写对应代码才能看到效果
addEventListener第三个参数传入 true 代表是捕获阶段触发(很少使用)
若传入false代表冒泡阶段触发,默认就是false
1 |
|
9.14事件冒泡
当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒跑
- 简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件
- 事件冒泡是一定会发生的(绑定事件的时候,第三个参数不传,就是默认允许事件冒泡)
1 | <body> |
9.15阻止事件冒泡
问题:因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素
需求:若想把事件就限制在当前元素内,就需要阻止事件冒泡
前提:阻止事件冒泡需要拿到事件对象
语法
注意:此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效(本质上是讲阻止流动,不仅会阻止冒泡而且会阻止捕获)
1 | <script> |
9.16事件解绑
能给元素对象绑定事件,就能把绑定的事件解除
removeEventListener(事件类型,事件处理函数,[获取捕获或者冒泡阶段])
1 | <script> |
补充:两种注册事件的区别
l传统on注册(L0)
同一个对象,后面注册的事件会覆盖前面注册(同一个事件)
直接使用null覆盖偶就可以实现事件的解绑
都是冒泡阶段执行的
事件监听注册(L2)
语法:addEventListener(事件类型,事件处理函数,是否使用捕获)
后面注册的事件不会覆盖前面注册的事件(同一个事件)
可以通过第三个参数去确定是在冒泡或者捕获阶段执行
必须使用removeEventListener(事件类型,事件处理函数,获取捕获或者冒泡阶段)
匿名函数无法被解绑
9.17事件委托
委托:班上的人一个人一个快递,快递小哥得给每个人送一次快递,快递小哥把快递交给班主任,班主任把快递给同学。(其中班主任可以看做父元素,每个同学可以看做子元素)
事件委托是利用事件流的特征解决一些开发需求的知识技巧
优点:减少注册次数,可以提高程序性能
原理:事件委托其实是利用事件冒泡的特点。
给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件
例如上面li:只需要给父元素注册一个事件,点击子元素因为有事件冒泡,所以会触发父元素的事件
1 | <body> |
问题:点哪个li都能触发父元素的事件,怎么知道是哪个子元素被触发了
父元素的元素对象身上有一个target的属性,里面存放的是哪一个子元素被触发了
1 | <body> |
问题:在父元素中,有很多的子元素,有些元素并需要触发父元素的事件,这个时候应该怎么去判断?如ul里面有li和其他的标签
1 | <body> |
9.18阻止默认行为
有些标签有默认的行为,如a标签会默认跳转,submit会自动提交,但是有些时候我们并不需要这些默认的行为,所以我们就需要取消这些默认的行为。
语法:
e.preventDefalut()
阻止a的默认行为,阻止它的跳转
1 | <body> |
9.19其他事件–页面加载事件(网站调优的时候会用)
有些时候需要等页面资源全部处理完了做一些事情,js是单线程的一门语言,所以加载资源也是线性加载的,如果有资源比较大,例如图片或者视频,如果没加载完,会影响到其他资源的加载。所以页面加载事件可以先加载其他的,最后在加载大型的资源
事件名:load(等待 loading….)
监听页面所有资源加载完毕:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<body>
<img src="一个需要远程请求回来的地址" alt="">
<script>
// window 对象是比document对象还大的一个对象
//等待所有的资源都加载完了在执行
window.addEventListener('load',function(){
// 需要执行的一些操作
})
// 等待图片加载完了在执行某些代码
const img=document.querySelector('img')
img.addEventListener('load',function(){
// 执行的代码
})
</script>
</body>事件名: DOMContentLoaded
当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像等完全加载后
给 document 添加 DOMContentLoaded 事件
9.20其他事件–元素滚动事件
很多网页需要检测用户把页面滚动到某个区域后做一些处理, 比如固定导航栏,比如返回顶部
事件名:scroll
监听整个页面滚动:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body{
height: 10000px;
}
</style>
</head>
<body>
<script>
//页面滚动事件,给window加多一点
window.addEventListener('scroll',function(){
alert("我滚了")
})
</script>
</body>
</html>我们想要页面滚动一段距离,比如100px,就让某些元素显示隐藏,那我们怎么知道,页面滚动了100像素呢?
scrollLeft和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
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<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
height: 100px;
width: 100px;
background-color: yellowgreen;
overflow: scroll;
}
</style>
</head>
<body>
<div>
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容 我是内容
我是内
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我是内容
我
我是内容
我是内容
我是内
我是内容
</div>
<script>
const div=document.querySelector("div")
div.addEventListener('scroll',function(){
// 被卷去的头部
console.log(div.scrollTop);
})
</script>
</body>
</html>想要获取到整个页面的滚动的特殊写法(固定或者说约定俗成的写法)
也就是说需要拿到html的滚动的距离
1
2
3
4
5
6
7<script>
window.addEventListener('scroll',function(){
//获取页面滚动了多少 也就是html的滚动
console.log(document.documentElement.scrollTop);
})
</script>给scrollTop赋值
也就是一开始就处于哪个位置
1
2
3
4
5<script>
//页面一加载就处于中间的位置
document.documentElement.scrollTop=800
</script>案例:滚动条到某个位置元素显示
1
2
3
4
5
6
7
8
9
10
11
12<script>
const div = document.querySelector('div')
window.addEventListener('scroll', function () {
let n = document.documentElement.scrollTop
console.log(n);
if (n >= 100) {
div.style.display = 'block'
}
})
</script>案例:电梯导航
点击对应的楼层,能显示对应楼层的内容
①:需要用到页面滚动事件
②:检测页面被卷去的头部,如果大于300,就让侧边栏显示
③:显示和隐藏配合css过渡,利用opacity加渐变效果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<script>
const dt=document.querySelector(".xtx-elevator")
// 页面滚动到对应的位置 显示电梯导航
window.addEventListener('scroll',function(){
let n=document.documentElement.scrollTop
if(n>300){
dt.style.opacity='1'
}else{
dt.style.opacity='0'
}
})
// 回到顶部
const backTop=document.querySelector("#backTop")
backTop.addEventListener('click',function(){
document.documentElement.scrollTop=0
})
</script>
9.21页面尺寸事件
会在窗口尺寸改变的时候触发事件
resize
1 | <script> |
- 获取元素的宽和高(不包含padding border)
获取元素的可见部分宽高(不包含边框,margin,滚动条等)
clientWidth和clientHeight
通过js来获取元素的宽度和高度
1 | <!DOCTYPE html> |
9.22元素尺寸与位置尺寸
获取元素宽高
Ø 获取元素的自身宽高、包含元素自身设置的宽高、padding、border
Ø offsetWidth和offsetHeight
Ø 获取出来的是数值,方便计算
Ø 注意: 获取的是可视宽高, 如果盒子是隐藏的,获取的结果是0
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<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
height: 100px;
width: 100px;
background-color: yellow;
padding: 100px;
border: 10px solid #ccc;
}
</style>
</head>
<body>
<div>
</div>
<script>
const div=document.querySelector('div')
console.log(div.offsetHeight);
console.log(div.offsetWidth);
</script>
</body>
</html>获取位置
Ø 获取元素距离自己定位父级元素的左、上距离
Ø offsetLeft和offsetTop 注意是只读属性
如果父元素没有定位,就默认是相对于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<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
/* position: relative; */
height: 100px;
width: 100px;
background-color: yellow;
padding: 100px;
border: 10px solid #ccc;
margin:100px;
}
</style>
</head>
<body>
<div>
<p>ddd</p>
</div>
<script>
const div=document.querySelector("div")
console.log(div.offsetTop);
console.log(div.offsetLeft);
</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<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.fa{
position: relative;
height: 200px;
width: 200px;
background-color: yellow;
border: 10px solid #ccc;
margin:100px;
}
.son{
position: absolute;
top: 100px;
left: 100px;
}
</style>
</head>
<body>
<div class="fa">
<div class="son">a</div>
</div>
<script>
const div=document.querySelector(".son")
console.log(div.offsetTop);
console.log(div.offsetLeft);
</script>
</body>
</html>
9.23元素尺寸与位置总结
10.节点操作
DOM树里每一个内容都称之为节点
节点类型
元素节点
所有的标签 比如 body、 div 、html 是根节点
属性节点
所有的属性 比如 href
文本节点
所有的文本
10.1查找结点
通过关系来获取节点,以前是直接获取节点,找到节点的爸爸,兄弟,儿子
父节点查找
parentNode 属性(只能找到最近的父元素节点)
返回最近一级的父节点 找不到返回为null
1
2
3
4
5
6
7
8
9
10
11
12
13<body>
<div class="fa">
<div class="son">
</div>
</div>
<script>
const son=document.querySelector('.son')
const fa=son.parentNode
console.log(fa);
</script>
</body>关闭广告案例
1
2
3
4
5
6
7
8
9
10
11
12<body>
<div>我是广告
<button>x</button>
</div>
<script>
const btn=document.querySelector('button')
btn.addEventListener('click',function(){
this.parentNode.style.display='none'
})
</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<body>
<div>我是广告
<button>x</button>
</div>
<div>我是广告
<button>x</button>
</div>
<div>我是广告
<button>x</button>
</div>
<script>
const btns=document.querySelectorAll('button')
for(let i=0;i<btns.length;i++){
btns[i].addEventListener('click',function(){
this.parentNode.style.display="none";
})
}
</script>
</body>子节点查找
childNodes
获得所有子节点、包括文本节点(空格、换行)、注释节点等
children 属性 (重点)
仅获得所有元素节点,亲儿子
返回的还是一个伪数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<body>
<ul>
<li>1</li>
<li>3</li>
<li>2</li>
<li>4</li>
</ul>
<script>
const ul=document.querySelector('ul')
const lis=ul.children
console.log(lis);
</script>
</body>查找兄弟节点
- 下一个兄弟节点
nextElementSibling 属性
- 上一个兄弟节点
previousElementSibling 属性
10.增加节点
一般情况下,我们新增节点,按照如下操作:
创建一个新的节点
把创建的新的节点放入到指定的元素内部
创建节点
即创造出一个新的网页元素,再添加到网页内,一般先创建节点,然后插入节点
追加节点
要想在界面看到,还得插入到某个父元素中
插入到父元素的最后一个子元素:
插入到父元素中某个子元素的前面
10.3删除节点
若一个节点在页面中已不需要时,可以删除它
语法
在 JavaScript 原生DOM操作中,要删除元素必须通过父元素删除
注意
如不存在父子关系则删除不成功
删除节点和隐藏节点(display:none) 有区别的: 隐藏节点还是存在的,但是删除,则从html中删除节点
10.4综合案例:学生信息表案例
核心思路:
①: 声明一个空的数组
②: 点击录入,根据相关数据,生成对象,追加到数组里面
③: 根据数组数据渲染页面-表格的 行
④: 点击删除按钮,删除的是对应数组里面的数据
⑤: 再次根据数组的数据,渲染页面
步骤一:录入模块
点击录入模块
(1). 首先取消表单默认提交事件
(2). 创建新的对象,里面存储 表单获取过来的数据,格式如右图
(3). 追加给数组
(4). 渲染数据。 遍历数组, 动态生成tr, 里面填写对应td数据, 并追加给 tbody
(5). 重置表单
(6). 注意防止多次生成多条数据,先清空 tbody
1 | <script> |
- 点击删除模块
点击删除模块
(1). 采用事件委托形式,给 tbody 注册点击事件
(2). 点击链接,要删除的是对应数组里面的这个数据,而不是删除dom节点,如何找到这个数据?
(3). 前面渲染数据的时候,动态给a链接添加 自定义属性 data-id=“0”,这样点击当前对象就知道索引号了
(4). 根据索引号,利用 splice 删除这条数据
(5). 重新渲染
1 | <script> |
11.BOM
BOM(Browser Object Model ) 是浏览器对象模型
基本上好多的对象都是基于window对象的
lwindow对象是一个全局对象,也可以说是JavaScript中的顶级对象
l像document、alert()、console.log()这些都是window的属性,基本BOM的属性和方法都是window的。
所有通过var定义在全局作用域中的变量、函数都会变成window对象的属性和方法
lwindow对象下的属性和方法调用的时候可以省略window
11.1定时器-延时函数
JavaScript 内置的一个用来让代码延迟执行的函数,叫 setTimeout,时间到了就执行,执行完了就没有了。
语法
清除定时函数
注意点
延时器需要等待,所以后面的代码先执行
每一次调用延时器都会产生一个新的延时器
两种定时器的区别
延时函数: 执行一次
间歇函数:每隔一段时间就执行一次,除非手动清除
案例:自动关闭广告案例
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<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
height: 100px;
width: 100px;
background: yellowgreen;
}
</style>
</head>
<body>
<div>
<button>X</button>
</div>
<script>
const div=document.querySelector('div')
setTimeout(function(){
div.style.display='none'
},3000)
</script>
</body>
</html>
11.2事件循环
js的执行机制
JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。
这是因为 Javascript 这门脚本语言诞生的使命所致——JavaScript 是为处理页面中用户的交互,以及操作
DOM 而诞生的。比如我们对某个 DOM 元素进行添加和删除操作,不能同时进行。 应该先进行添加,之后再删除。
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是:如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
同步异步
为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程。于是,JS 中出现了同步和异步。
**同步:**前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。比如做饭的同步做法:我们要烧水煮饭,等水开了(10分钟之后),再去切菜,炒菜。
**异步:**你在做一件事情时,因为这件事情会花费很长时间,在做这件事的同时,你还可以去处理其他事情。比如做饭的异步做法,我们在烧水的同时,利用这10分钟,去切菜,炒菜。
1
2
3
4
5
6
7
8console.log(1)
document.addEventListener('click', function () {
console.log(4)
})
console.log(2)
setTimeout(function () {
console.log(3)
}, 3000)
11.2location 对象
location 对象也是windiow中的一个对象
location 的数据类型是对象,它拆分并保存了 URL 地址的各个组成部分
常用属性和方法:
href 属性获取完整的 URL 地址,对其赋值时用于地址的跳转
案例:
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<!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>
<a href="https://www.baidu.com">五秒后跳转</a>
<script>
const a=document.querySelector('a')
let num=5
let id= setInterval(function(){
num--
a.innerHTML=`${num}秒后跳转`
if(num===0){
clearInterval(id)
location.href='www.baidu.com'
}
},1000)
</script>
</body>
</html>search 属性获取地址中携带的参数,符号 ?后面部分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<!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>
<form action="">
<input type="text" name="pas">
<input type="password" name="password id="">
<button>提交</button>
</form>
<script>
console.log(location.search);
</script>
</body>
</html>hash 属性获取地址中的哈希值,符号 # 后面部分(spa单页面应用)
后期vue路由的铺垫,经常用于不刷新页面,显示不同页面,比如 网易云音乐
reload 方法用来刷新当前页面,传入参数 true 时表示强制刷新
总结
location.href 属性获取完整的 URL 地址,对其赋值时用于地址的跳转
search 属性获取地址中携带的参数,符号 ?后面部分
hash 属性获取地址中的啥希值,符号 # 后面部分
reload 方法用来刷新当前页面,传入参数 true 时表示强制刷新
11.4navigator对象
里面放的都是浏览器相关的信息,之前是用于判断是否是ie浏览器,如果是ie浏览器就怎么怎么样。
navigator的数据类型是对象,该对象下记录了浏览器自身的相关信息
通过 userAgent 检测浏览器的版本及平台
1
2
3
4
5
6
7
8
9
10// 检测 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' }
})()
11.5 histroy对象
history 的数据类型是对象,主要管理历史记录, 该对象与浏览器地址栏的操作相对应,如前进、后退、历史记录等
- history的常用的方法
1 | <body> |
11.6本地存储
- 本地存储是什么?
随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,HTML5规范提出了相关解决方案。
说白了本地存储就是浏览器中的一个小仓库
本地存储简介
1、数据存储在用户浏览器中
2、设置、读取方便、甚至页面刷新不丢失数据
3、容量较大,sessionStorage和localStorage约 5M 左右
11.7 本地存储-localStorage
作用: 可以将数据永久存储在本地(用户的电脑), 除非手动删除,否则关闭页面也会存在
特性:
可以多窗口(页面)共享(同一浏览器可以共享)
以键值对的形式存储使用
存储数据
1
2// 存储一个数据
localStorage.setItem('name','王英强')1
2
3// 取一个数据
localStorage.getItem('name')
console.log(localStorage.getItem('name'));1
2//删除一个数据
localStorage.removeItem('name')1
2//更改一个数据
localStorage.setItem('name','张三')注意:本地存储只能存储字符串类型的数据
11.8sessionStorage(使用的较少)
特征
生命周期为关闭浏览器窗口
在同一个窗口(页面)下数据可以共享
以键值对的形式存储使用
用法跟localStorage 基本相同
11.9存储复杂数据类型
本地只能存储字符串,无法存储复杂数据类型
存储复杂数据类型,不能直接使用
1 | <script> |
存储复杂数据类型必须转化为JSON字符串存储
JSON.stringify(复杂数据类型):将复杂的数据类型转化为JSON类型的字符串
1 | <script> |
存储进去的是JSON类型的字符串,取出来也是JSON类型的字符串
使用的时候需要将JSON类型的数据转化成为对象
**语法:JSON.parse(JSON字符串)**:把JSON字符串转换为对象
1 | <script> |
12.正则表达式
正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象
作用
例如验证表单:用户名表单只能输入英文字母、数字或者下划线, 昵称输入框中可以输入中文(匹配)比如用户名: /^[a-z0-9_-]{3,16}$/
Ø 过滤掉页面内容中的一些敏感词(替换),
从字符串中获取我们想要的特定部分(提取)等 。
语法
我们想要查找是否有戴眼镜的人, 怎么做呢?
定义规则: 戴眼镜的
根据规则去查找:找到则返回
正则同样道理,我们分为两步:
定义规则
查找
1. 定义正则表达式语法:
1
2
3
4
5
6
7<script>
const str="我喜欢吃螺蛳粉,一天三顿都是螺蛳粉"
// 定义正则表达式语法
const regObj=/螺蛳粉/
</script>2.判断是否有符合规则的字符串:
test() 方法 用来查看正则表达式与指定的字符串是否匹配
1
2
3
4
5
6
7
8
9
10
11
12<script>
const str="我喜欢吃螺蛳粉,一天三顿都是螺蛳粉"
// 定义正则表达式语法
const regObj=/螺蛳粉/
//判断是否符合规则 如果符合就返回true 否则就返回false
regObj.test(str)
console.log(regObj.test(str));
</script>