JavaScript最新

1.JavaScript简介

1.1JavaScript 简介

  • js 是什么

    是一种运行在客户端(浏览器)的编程语言,实现人机交互效果.

  • js 能做什么(作用)

    1. 网页特效 (监听用户的一些行为让网页作出对应的反馈)
    2. 表单验证 (针对表单数据的合法性进行判断)
    3. 数据交互 (获取后台的数据, 渲染到前端)
    4. 服务端编程 (node.js
  • js 的组成

    js的组成

1.2 js的书写位置

  • 内部js

    理论上写在哪里都可以,但是最好是写在body的最下面。

    内部js

  • 外部js

    后续程序的开发中最常用的一种方式,将逻辑和样式进行了分离,方便代码的复用,维护。

    外部js

  • 行内js

    和css一样写在标签内的js,前期用的少,后期学到vue用的会非常多。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <!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>
    <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
    2
    let 变量名
    //声明变量有两部分构成:声明关键字、变量名(标识)

    声明变量有两部分构成:声明关键字、变量名(标识)

    let 即关键字 (let: 允许、许可、让、要),所谓关键字是系统提供的专门用来声明(定义)变量的词语.

  • 变量的赋值

    定义了一个变量后,你就能够初始化它(赋值)。在变量名之后跟上一个“=”,然后是数值

    变量

    注意:是通过变量名来获得变量里面的数据

  • 变量的初始化

简单点,也可以声明变量的时候直接完成赋值操作,这种操作也称为 变量初始化。

1
2
3
let age=100;

alert(age)
  • 变量练习

    作业练习2

2.2变量的基本使用

掌握变量的更新以及了解同时声明多个变量的写法

  • 变量的更新

    更新age的值

    1
    2
    3
    4
    5
    let age=100;
    age=20;

    //let age=100;
    //使用let修饰的变量就不能重复声明
  • 声明多个变量

    1
    2
    let a=100,b=10;
    //声明多个变量 虽然这样写比较简答, 但是不提倡这样声明,这样的话不利于代码的语义化
  • 输入用户名称然后弹出案例

    1. 用户输入数据
    2. 将数据保存下来
    3. 将数据打印下来
    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 变量的命名规范与规则

规则:必须遵守,不遵守报错 (法律层面)

规范:建议,不遵守不会报错,但不符合业内通识 (道德层面

  • 规则

    1. 不能用关键字:有特殊含义的字符,JavaScript 内置的一些英语词汇。例如:let、var、if、for等
    2. 只能用下划线、字母、数字、$组成,且数字不能开头\
    3. 字母严格区分大小写,如 Age 和 age 是不同的变量
  • 规范

    1. 起名要有意义
    2. 遵守小驼峰命名法:第一个单词首字母小写,后面每个单词首字母大写。例: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关键字的一些问题

    1. 可以先使用 在声明 (不合理)
    2. var 声明过的变量可以重复声明(不合理)
    3. 比如变量提升、全局变量、没有块级作用域等等
  • 结论

    使用var关键字会给我们的程序编写带来很多的问题,所以我们现在基本都是使用let来代替var,但是在一些较为古老的程序中我们依然可以看到var的存在,所以关于var 我们需要做一些简单的了解。


2.6 数组

变量一次只能存几个值? 如果我想保存一个班里5个人的姓名怎么办?

  • 声明数组

    1
    let arr=["张三","李四","王五"]
  • 数组简介

    1. 数组是按顺序保存,所以每个数据都有自己的编号
    2. 计算机中的编号从0开始
    3. 在数组中,数据的编号也叫索引或下标
    4. 数组可以存储任意类型的数据
    5. 数组中数据的个数,通过数组的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.数据类型

计算机程序可以处理大量的数据,为什么要给数据分类?

  1. 更加充分和高效的利用内存 2. 也更加方便程序员的使用数

3.1数据类型分类

  • js的数据类型主要是分为两类

    1. 基本数据类型
    2. 引用数据类型
  • 弱数据类型的语言

    js是弱数据类型的语言,java是强数据类型的语言。

    js只有当我们赋值了才知道是什么类型的数据。弱数据类型的语言学习起来比较简单

3.32数字类型Number

  • 数字可以有很多操作,比如,乘法 * 、除法 / 、加法 + 、减法 - 等等,所以经常和算术运算符一起。 数学运算符也叫算术运算符,主要包括加、减、乘、除、取余(求模)
  1. +:求和
  2. -:求差
  3. *:求积
  4. /:求商
  5. %:取模(取余数) 开发中经常作为某个数字是否被整除
  • 同时使用多个运算符编写程序时,会按着某种顺序先后执行,我们称为优先级。 JavaScript中 优先级越高越先被执行,优先级相同时以书从左向右执行

    1. 乘、除、取余优先级相同
    2. 加、减优先级相同
    3. 乘、除、取余优先级大于加、减
    4. 使用 () 可以提升优先级
    5. 总结: 先乘除后加减,有括号先算括号里面的~~
  • 案例:计算圆的面积

    需求: 弹出输入框,邀请用户输入半径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
    4
    let name='张三'
    let age="20"
    let goods=`小米`
    let str=''
  • 注意

    1. 无论单引号或是双引号必须成对使用
    2. 单引号/双引号可以互相嵌套,但是不以自已嵌套自已(口诀:外双内单,或者外单内双)
    3. 必要时可以使用转义符 \,输出单引号或双引号
  • 字符串拼接(数字相加,字符相连)

    + 运算符 可以实现字符串的拼接

    1
    2
    3
    4
    5
    log('我是'+'张三')
    let name='张三'
    let age='23'

    log(name+age)
  • 模板字符串

    使用场景:拼接字符串和变量,在没有它之前,要拼接变量比较麻烦

    1. `` (反引号) 在英文输入模式下按键盘的tab键上方那个键(1左边那个键)
    2. 内容拼接变量时,用 ${ } 包住变量
    1
    2
    3
    log('大家好'+name+'我今年'+age)//普通字符串拼接

    log(`大家好我是 ${name} 我今年${age}`)
  • 用户输入案例:

    需求:需求:页面弹出对话框,输入名字和年龄,页面显示: 大家好,我叫xxx,今年xx岁

3.4 布尔类型 boolean

  • 表示肯定或否定时在计算机中对应的是布尔类型数据。 它有两个固定的值 true 和 false,表示肯定的数据用 true(真),表示否定的数据用 false(假)

    1
    2
    3
    let istru=true

    log(2>8)

3.5未定义类型undefined

声明一个变量但是未给值就叫做未定义

  • 未定义是比较特殊的类型,只有一个值 undefined。
  • 工作中的使用场景: 我们开发中经常声明一个变量,等待传送过来的数据。 如果我们不知道这个数据是否传递过来,此时我们可以通过检测这个变量是不是undefined,就判断用户是否有数据传递过来

3.6空类型 null

  • JavaScript 中的 null 仅仅是一个代表“无”、“空”或“值未知”的特殊值,null是一个对象,如果我们想定义一个对象但是暂时没有值,我们可以先声明一个null类型来占位
  • 将来有个变量里面存放的是一个对象,但是对象还没创建好,可以先给个null

3.7 检测数据类型

  • 通过 typeof 关键字检测数据类型

  • typeof 运算符可以返回被检测的数据类型。它支持两种语法形式:

    1. 作为运算符: typeof x (常用的写法)
    2. 函数形式: typeof(x)
    1
    2
    3
    4
    5
    let age=16
    let name="zhangsan"
    let istrue=false
    let buy
    log(typeof age).....

3.8类型的转换

JavaScript是弱数据类型: JavaScript也不知道变量到底属于那种数据类型,只有赋值了才清楚。 坑: 使用表单、prompt 获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法运算。

1
log('100'+'100')//100100 输出的结果

就是把一种数据类型转换成我们需要的数据类型

  • 隐式数据类型转换

    某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换称为隐式转换。

    1. 号两边只要有一个是字符串,都会把另外一个转成字符串
    2. 除了+以外的算术运算符 比如 - * / 等都会把数据转成数字类型
    1
    console.log(1+'1')// '11'
    1
    2
    log(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
    4
    log(parseInt('12'))// 输出数字类型的12
    log(parseInt('12.123'))// 输出数字类型的12
    log(parseInt('12.1px'))// 输出数字类型的12
    log(parseInt('12px'))// 输出数字类型的12

    parseFloat(数据)— 包含小数

    1
    2
    3
    4
    log(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. 静态样式
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
<!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>
table,th,td{
border: 1px solid #ccc;
padding: 5px 10px;
text-align: center;
}

/* 合并边框 */
table{
border-collapse: collapse;
margin-top: 20px;
margin: 0 auto;
}

h2{
text-align: center;
}
</style>
</head>
<body>
<h2>订单信息</h2>
<table>
<tr>
<th>商品名称</th>
<th>商品价格</th>
<th>商品数量</th>
<th>商品总价</th>
<th>发货地址</th>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
</table>
</body>
</html>
  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
    7
    let num=1
    num+1
    alert(num)// 输出的结果还是1 ,原因是num+1 的值并没有重新赋值给num

    // 采用赋值运算符的方式
    num+=1//相当于num=mum+1
    </script>

4.2一元运算符

我们以前让一个变量每次+1 ,以前我们做的呢?

  • 自减

    符号:–

    作用:让变量的值 -1

  • 自增

    符号:++

    作用:让变量的值 +1

  • 使用场景:经常用于计数来使用。 比如进行10次操作,用它来计算进行了多少次了

  • 前置自增和后置自增(了解即可,两者几乎没有区别)

    1
    2
    3
    let i=1

    log(++i+2)//前置自增,i先自增,在和后面的2 相加
    1
    2
    3
    let 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
2
3
x=7
4+4
num++

语句是一段可以执行的代码

1
prompt() 可以弹出一个输入框,还有 if语句 for 循环语句等

5.2 流程控制语句介绍

  • 以前我们写的代码,写几句就从上往下执行几句,这种叫顺序结构 -

  • 有的时候要根据条件选择执行代码,这种就叫分支结构

  • 某段代码被重复执行,就叫循环结构

    三大流程控制语句

5.3 分支语句 if

分支语句可以让我们选择性的执行某一段代码

  • 分支语句包括

    • If分支语句
    • 三元运算符
    • switch 语句
  • if语句有三种使用:

    单分支、双分支、多分支

  • if 语句的单分支

    if

    • 括号内的条件为true时,进入大括号里执行代码
    • 小括号内的结果若不是布尔类型时,会发生隐式转换转为布尔类型
  • if 单分支练习

    用户输入成绩,如果成绩大于60,弹出”成绩合格“

  • 双分支if语法:

    if2

  • if 多分支语法练习

    用户输入,用户名:admin,密码:123456, 则提示登录成功,否则提示登录失

    ①:弹出输入框,分别输入用户名和密码

    ②:通过if语句判断,如果用户名是admin,并且密码是123456,则执行if里面的语句,否则执行else 里面的语句。

  • if 多分支语法练习2

    让用户输入年份,判断这一年是闰年还是平年并弹出对应的警示框

    分析:

    ①:能被4整除但不能被100整除,或者被400整除的年份是闰年,否则都是平年

    ②:需要逻辑运算

  • 多分支if语法

    使用场景: 适合于有多个结果的时候, 比如学习成绩可以分为: 优 良 中

    if3

    • 先判断条件1,若满足条件1就执行代码1,其他不执行
    • 若不满足则向下判断条件2,满足条件2执行代码2,其他不执行
    • 若依然不满足继续往下判断,依次类推
    • 若以上条件都不满足,执行else里的代码n
    • 注:可以写N个条件,但这里演示只写2个
  • 多分支if语法 案例

    iflx

    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语句实现分支效果的时候,可以使用三元运算符

  • 语法

    ? 与 : 配合使用

    syys

  • 案例

    三元运算符练习

    1
    2
    3
    4
    5
    6
    7
    8
     <script>

    let num1= parseInt( prompt("请输入第一个数"))
    let num2= parseInt( prompt("请输入第二个数"))

    alert(num1>num2?'第一个数比较大':'第二个数 比较大')

    </script>

5.5分支语句 switch

找到满足条件的值然后直接执行后续的语句

switch

  • 解释

    找到跟小括号里数据全等的case值,并执行里面对应的代码

    若没有全等 === 的则执行default里的代码

    例:数据若跟值2全等,则执行代码2

  • 注意

    1. switch case语句一般用于等值判断,不适合于区间判断
    2. 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循环 就是在满足条件期间,重复执行某些代码。

  • 基本语法

  • 解释

    1. 跟if语句很像,都要满足小括号里的条件为true才会进入 循环体 执行代码
    2. while大括号里代码执行完毕后不会跳出,而是继续回到小括号里判断条件是否满足,若满足又执行大括号里的代码,然后再回到小括号判断条件,直到括号内条件不满足,即跳出
  • 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. 页面输入1-100
    2. 计算从1加到100 的和并输出
    3. 计算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
    10
    let 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

简易的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

  • 作用重复执行代码

  • 优点:把声明起始值、循环条件、变化值写到一起,让人一目了然,它是最常使用的循环形式

    for循环

    1
    2
    3
    4
    //利用for循环输出三句话
    for(let i=0;i<=3;i++){
    alert("输出")
    }
  • for循环练习

    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循环执行完成了以后才会执行外面的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
    2
    let arr=[]
    arr[0]=1

    更改数组中元素的值

    1
    2
    3
    4
    let 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() 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度 (重点)

    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(新增的内容) 方法将一个或多个元素添加到数组的开头,并返回该数组的新长度

    unShift

    1
    2
    3
    4
    5
    let 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() 方法从数组中删除最后一个元素,并返回该元素的值

    pop

    1
    2
    3
    let arr= [2, 0, 6, 1, 77, 0, 52, 0, 25, 7]
    // 删除数组中的最后一个元素
    arr.pop()

    数组. shift() 方法从数组中删除第一个元素,并返回该元素的值

    删除第一个元素

    1
    2
    3
    4
    5
    let arr= [2, 0, 6, 1, 77, 0, 52, 0, 25, 7]
    // 删除数组中的第一个元素
    arr.shift()

    console.log(arr);

    数组. splice() 方法 删除指定元素

    起始位置:开始删的位置,删除第几个

    splice

    1
    2
    3
    4
    5
    let 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
    <!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>
    *{
    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
    <!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>
    * {
    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
    6
    function 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
    10
    function 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
    5
    function Sum(a,b){
    console.log(a+b);
    }

    Sum()//调用函数但是未传参
  • 参数默认值

    我们可以改进下,用户不输入实参,可以给 形参默认值,可以默认为 0, 这样程序更严谨,可以如下操作:

    1
    2
    3
    function Sum(a=0,b=0){
    console.log(a+b);
    }

    如果有参数就是用传递过来的参数,如果没有传递就使用默认值。

6.3函数案例

需求:学生的分数是一个数组,计算每个学生的总分

分析:

①: 封装一个求和函数

②: 传递过去的参数是一个数组

③: 函数内部遍历数组求和

1
2
3
4
5
6
7
8
function arrSum(arr=[]){
let sum=0
for(let i=0;i<arr.length;i++){
sum+=arr[i]
}
}

arrSum([1,2,3,4,5])

用户输入x和y这两个数,写一个函数,使用这个函数来打印从x-y的和

1
2
3
4
5
6
7
8
9
10
11
12
function sum(start,end){
let add=0
for(let i=start;i<=end;i++){
add+=i
}
console.log(add);
}

let num1=parseInt(prompt("请输入数据1"))
let num2=parseInt(prompt("请输入数据2"))

sum(num1,num2)

6.4 函数的返回值

函数是被设计为执行特定任务的代码块

我们执行完成指定的任务后,把结果返回给调用者,如原材料送去加工,把加工的成品返回给我们

当调用某个函数,这个函数会返回一个结果出来,这就是有返回值的函数

函数的返回值

  • 函数返回值

    当函数需要返回数据出去时,用return关键字

  • 语法

    函数返回值

    return 返回的值是函数的调用者

    1
    2
    3
    4
    5
    6
    7
    8
     function fn(){
    return 20
    }
    //相当于 fn()=20 也就是说把结果给了调用者fn()

    //常写的形式
    let a=fn()
    //相当于 a=fn()=20
  • 案例

    求和哈数

    1
    2
    3
    4
    5
    function  add(a=0,b=0){
    return a+b
    }

    let numAdd=add(1,2)
  • 注意

    • return 后面代码不会再被执行,会立即结束当前函数,所以 return 后面的数据不要写代码,return 后面的数据不要换行写
    • 并不是所有的函数都需要返回值,没有return的函数默认是undefine
    1
    2
    3
    4
    5
    6
    function  add(a=0,b=0){
    return
    a+b //不会执行
    }

    let numAdd=add(1,2)
1
2
3
4
5
6
7
8
9
10
- 练习

![返回值练习](/img/js/1fhzlx.jpg)

```js
function getMax(x,y){
return x>y?x:y
}

let max=getMax(1,3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 求最大数组的最大值
function getArrMax(arr=[]){
//准备一个max变量存放数组的最大值
let max=arr[0]

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

if(max<arr[i]){
max=arr[i]
}

}

return max
}

getArrMax([1,2,4,5,77])

一次性求最大值和最小值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 // 求最大数组的最大值
function getArrMax(arr=[]){
//准备一个max变量存放数组的最大值
let max=arr[0]

let min=arr[0]

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

if(max<arr[i]){
max=arr[i]
}

if(min<arr[i]){
min=arr[i]
}

}

return [max,min]
}

let arr= getArrMax([1,2,4,5,77])

6.5 函数细节补充

  • 两个相同的函数后面的会覆盖前面的函数(不建议写两个函数名相同的函数)

  • 在Javascript中 实参的个数和形参的个数可以不一致

    如果形参过多 会自动填上undefined (了解即可)

    如果实参过多 那么多余的实参会被忽略 (函数内部有一个arguments,里面装着所有的实参)

    1
    2
    3
    4
    5
    function fun(a,b){
    log(a,b)
    }

    fun(1,2,3) //剩余的实参不参与运算
    1
    2
    3
    4
    5
    function 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
    13
    let num=0  //全局作用域

    console.log(num);

    function addNum(){

    let a=0 //局部变量,在函数里面的就是局部变量
    //局部变量就是只能在当前的函数里面使用的

    return num+a
    }

    let add= addNum()
  • 在JavaScript中,根据作用域的不同,变量可以分为:

    局部变量

6.7 作用域的特殊情况

如果函数内部,变量没有声明,直接赋值,也当全局变量看,但是强烈不推荐

1
2
3
4
5
function fn(){
num=20
}

fn()

但是有一种情况,函数内部的形参可以看做是局部变量。

1
2
3
4
5
function fn(a=0){ //函数内部的形参可以看做局部变量
return a
}

fn()

6.9作用域的冲突情况

  • 在不同作用域下,可能存在变量命名冲突的情况,到底改执行谁呢?

    作用域

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    let num1=10
    function fun(){


    let num1=20;

    function fun2(){
    let num1=30

    // 查找的时候先从当前的作用域找,接着一层一层王外面找
    console.log(num1);
    }

    fun2()
    }
  • 变量访问的规则

    只要是代码,就至少有一个作用域

    写在函数内部的局部作用域

    如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域\

    访问原则:在能够访问到的情况下 先局部, 局部没有在找全局

  • 案例

    结果是几

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function f1 () {
    let num = 123
    function f2 () {
    console.log(num)
    }
    f2()
    }
    let num = 456
    f1()

    结果是几

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function 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
    16
    let 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
2
3
4
5
6
7
(function(){
let num=10
})();

(function(){
let num=20
})();

第一个小括号里面包裹的是一个函数,第二个小括号是调用前面的函数,所以立即执行函数在写完了就直接调用,本质上就是调用前面的函数。

1
2
3
(function(x,y){
log(x,y)
})(1,2);

6.12时间转换案例

时分秒练习

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
<script>

// 1.获取用户输入
let s=parseInt(prompt("请输入秒数"))

//2. 封装函数
function getTime(t){

let h= parseInt(t / 60 / 60 % 24)
let m = parseInt(t / 60 % 60 )
let s = parseInt(t % 60)

// 3.补0操作

h<10?'0'+h:h
m<10?'0'+m:m
s<10?'0'+s:s

return `${h}小时${m}分钟${s}秒 `

}

let time= getTime(s)

alert(time)
</script>

6.13逻辑中断

开发中,还会见到以下的写法:

逻辑中断

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>


// 逻辑与 一边为假则不考虑另外一边
console.log(false&& 1);


// -----------------------------------------------
let a=10

console.log(false&& a++); //因为左边为假,所以右边不会执行

console.log(a);
// ------------------------------------------------



//逻辑或 一真则真,左边为真就不考虑另外一边

console.log(true || false); //一真则真

// ------------------------------------------------
let i=10

console.log(true || i++);

console.log(i);

// ------------------------------------------------



</script>

逻辑中断

  • 短路:只存在于 && 和 || 中,当满足一定条件会让右边代码不执行

6.14 补充:隐式数据类型转换补充

  • 转化为Boolean的类型的数据总结

    1. “” 空的字符串
    2. 0
    3. undefined
    4. null
    5. false
    6. 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 ,结果是 “1”
    2. 减法 - (像大多数数学运算一样)只能用于数字,它会使空字符串 “” 转换为 0
    3. null 经过数字转换之后会变为 0
    4. undefined 经过数字转换之后会变为 NaN
    1
    2
    3
    4
    5
    console.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
    4
    let 对象名={
    属性名:属性值,
    方法名:函数
    }

    对象就是去描述这个事物

  • 属性:

    数据描述性的信息称为属性,如人的姓名、身高、年龄、性别等,一般是名词性的。

    属性

    属性都是成 对出现的,包括属性名和值,它们之间使用英文 : 分隔

    多个属性之间使用英文 , 分隔

    属性就是依附在对象上的变量(外面是变量,对象内是属性)

    属性名可以使用 “” 或 ‘’,一般情况下省略,除非名称遇到特殊符号如空格、中横线等

    1
    2
    3
    4
    5
    let 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
2
3
4
5
6
7
8
9
10
//对象的声明
let xiaohong={
name:"小红",
age=39,
gender:'男'
}


//向数组中添加属性
xiaohong.hobby='编程'

属性–删(了解)

1
2
3
4
5
6
7
8
//对象的声明
let xiaohong={
name:"小红",
age=39,
gender:'男'
}

delete xiaohong.age

练习:

对象增删改查练习

7.3 对象的方法

数据行为性的信息称为方法,如跑步、唱歌等,一般是动词性的,其本质是函数。

对象方法

  1. 方法是由方法名和函数两部分构成,它们之间使用 : 分隔
  2. 多个属性之间使用英文 , 分隔
  3. 方法是依附在对象中的函数
  4. 方法名可以使用 “” 或 ‘’,一般情况下省略,除非名称遇到特殊符号如空格、中横线等
  • 调用对象中的方法

    声明对象,并添加了若干方法后,可以使用 . 调用对象中函数,称之为方法调用。

    也可以添加实参和形参数

    对象的调用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    let people={

    name:"张三",
    age:10,
    sayHi:function(name){
    alert(name+'你好')
    }

    }

    people.sayHi('王五')
  • 练习:写一个对象person,有姓名性别,年龄这些属性。还有唱 跳 rap方法

7.4 遍历对象(重点)

for 遍历对象的问题:

对象没有像数组一样的length属性,所以无法确定长度

对象里面是无序的键值对, 没有规律. 不像数组里面有规律的下标

  • 遍历对象

    遍历对象

    forin 遍历数组(能遍历数组 但是我们不推荐使用forin来遍历数组)

    1
    2
    3
    4
    5
    let 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
2
3
4
5
6
7
// 定义一个存储了若干学生信息的数组
let students = [
{name: '小明', age: 18, gender: '男', hometown: '河北省'},
{name: '小红', age: 19, gender: '女', hometown: '河南省'},
{name: '小刚', age: 17, gender: '男', hometown: '山西省'},
{name: '小丽', age: 18, gender: '女', hometown: '山东省'}
]
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>
// 定义一个存储了若干学生信息的数组
let students = [
{ name: '小明', age: 18, gender: '男', hometown: '河北省' },
{ name: '小红', age: 19, gender: '女', hometown: '河南省' },
{ name: '小刚', age: 17, gender: '男', hometown: '山西省' },
{ name: '小丽', age: 18, gender: '女', hometown: '山东省' }
]

// 遍历数组
for (let i = 0; i < students.length; i++) {

console.log(i);
console.log(students[i]); //students[i]能拿到数组中的每一个对象

console.log(students[i].name); //能拿到当前对象中的名字

for (let key in students[i]) {
//students[i]当前对象 ,students[i][key]当前对象['属性名']
console.log(students[i][key]);
}

}
</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
    <!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>
    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
    3
    Math.floor(Math.random()*(10+1))
    //Math.random()*(10+1) 是取的0-11 包含0 不包含11 的随机数
    //Math.floor() 向下取整,最大值只能是10 例如10.99 向下取整为10

    生成0-10之间的随机数(0的概率极少)

    1
    2
    Math.ceil(Math.random()*10) 
    //Math.ceil() 向上取整 9.1 取整为10

    生成0-10之间的随机数(round四舍五入,即生成0-10的随机整数数,取0和10的概率是其他数的一半

    1
    2
    Math.round(Math.random()*10) 
    //如 1.2 为1 1.6 为2

    通过随机数取数组中的一个随机的元素(重要)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    let 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
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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>学车在线首页</title>
<link rel="stylesheet" href="./css/style.css">
<style>

</style>
</head>

<body>


<script>
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
},
]



document.write(`
<div class="box w">
<div class="box-hd">
<h3>精品推荐</h3>
<a href="#">查看全部</a>
</div>
<div class="box-bd">
<ul class="clearfix">`)
// 循环遍历li标签,将data中的元素渲染到页面里面

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

document.write(`

<li>
<a href="#">
<img src=${data[i].src} alt="">
<h4>
${data[i].title}
</h4>
<div class="info">
<span>高级</span> • <span>${data[i].num}</span>人在学习
</div>
</a>
</li>

`)
}

document.write(` </ul>
</div>
</div>`)

</script>
</body>

</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
    14
    let num1=10
    let num2=num1
    num2=20
    log(num1)//?


    //--------------------------------------
    let obj1={ age:10 }

    let obj2=obj1

    obj2.age=30

    log(obj1.age )

学到这里你已经掌握了JavaScript的基础的语法了。能写一些简单的案例,已经相当棒了。像变量,函数,循环,数据类型,对象等等。剩下的时间需要我们学习webApi主要的内容为:

  1. DOM获取元素,获取页面中的元素。
  2. DOM-事件,注册事件、tab栏切换
  3. 事件对象,事件委托
  4. DOM节点操作
  5. BOM浏览器操作
  6. 正则表达式
  7. js项目实战

8.webAPI–DOM对象

8.1声明变量const 优先

建议: const 优先,尽量使用const,

原因是:const 语义化更好

很多变量我们声明的时候就知道他不会被更改了,那为什么不用 const呢?

有变量先使用const 如果发现他后面被修改在改为let

能否修改为const

能修改

下面代码的let可以改为const吗?

1
2
3
4
5
6
7
8
let arr =[1,2,3,4,5]
arr[0]=12

let person={
name:"王五"
}

person.name="王五五"

可以: 原因是复杂数据类型是栈里面存放的是地址,数据是存放在堆里面的。修改的话只是改变堆里面的数据,栈里面地址并没有发生改变,也就是说存储的值并没有发生改变。

1
2
3
let arr=[1,2,4,5]

arr=['1','4','4']

以上的情况是不行的,原因是给了变量一个新的数组,那么就是相当于开辟了一个新的地址(新的数组开辟新的地址),所以说这种情况是不行的。

地址

  • 什么时候使用const 什么时候使用let
    为什么const声明的对象可以修改里面的属性?

因为对象是引用类型,里面存储的是地址,只要地址不变,就不会报错

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

什么时候使用let声明变量?

如果基本数据类型的值或者引用类型的地址发生变化的时候,需要用let

比如 一个变量进行加减运算,比如 for循环中的 i++

8.2 API的作用和分类–DOM

  • 作用: 就是使用 JS 去操作 html 和浏览器

  • 分类:DOM (文档对象模型)、BOM(浏览器对象模型)

    简单来说就是可以通过js来控制页面中的元素,放大缩小,点击以后产生效果等等。

dom

  • DOM

    DOM(Document Object Model——文档对象模型)是用来呈现以及与任意 HTML 或 XML文档交互的API

    白话:DOM是浏览器提供的一套专门用来 操作网页内容 的功能

    例如:通过js来操作网页里面的内容

  • DOM树

    将 HTML 文档以树状结构直观的表现出来,我们称之为文档树或 DOM 树

    描述网页内容关系的名词WWWWW

    作用:文档树直观的体现了标签与标签之间的关系

    DOM树

  • DOM对象(重要)

    浏览器根据html标签生成的 JS对象

    1. 所有的标签属性都可以在这个对象上面找到,(所有的标签拿到之后都是以对象的形式展现的,只要是对象都会有属性和方法 )
    2. 修改这个对象的属性会自动映射到标签身上

    element

    DOM演示

    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

    document

    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等数组方法

    哪怕是只有一个元素,返回给我们的也是伪数组

    all

    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>
  • 总结

    1. . 获取页面中的标签我们最终常用那两种方式?

      • querySelectorAll()
      • querySelector()
    2. 他们两者的区别是什么?

      • querySelector() 只能选择一个元素, 可以直接操作

      • querySelectorAll() 可以选择多个元素,得到的是伪数组,需要遍历得

        到每一个元素

    3. 他们两者小括号里面的参数有什么注意事项?

      • 里面写css选择器
      • 必须是字符串,也就是必须要加引号
  • 其他获取DOM元素的方法(了解,以前使用,现在慢慢被淘汰)

    其他获取DOM元素的方法

8.4操作元素的内容

目标是能欧修改元素里面的文本内容

DOM对象都是根据标签生成的,所以操作标签,本质上就是操作DOM对象。

就是操作对象使用的点语法。

如果想要修改标签元素的里面的内容,则可以使用如下几种方式:

  1. 对象.innerText 属性
  2. 对象.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操作样式属性

  1. 通过 style 属性操作CSS
  2. 操作类名(className) 操作CSS
  3. 通过 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>
  • 注意

    1. 由于class是关键字, 所以使用className去代替
    2. 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的区别

    1. 修改大量样式的更方便
    2. 修改不多样式的时候方便
    3. classList 是追加和删除不影响以前类名

8.9 综合案例 随机轮播图

页面一刷新就随机的换一张图片,切换一个小点,同时换一个标题

轮播图

整体思路

  1. 首先看结构, css 样式不用管他。
  2. 小圆点,图片,标题是否都是同一个对象中的内容。
  3. 是否要生成一个随机数, 将对应的对象选渲染到页面上

详细思路

分析:

①: 准备一个数组对象,里面包含详细信息(素材包含)

②: 随机选择一个数字,选出数组对应的对象,更换图片,底部盒子背景颜色,以及文字内容

③: 利用这个随机数字,让小圆点添加高亮的类(addClass) 利用css 结构伪类选择器

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
<!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;
}

.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></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)' },
]

// 2.需要一个随机数,作为数组的下标

//2.1 生成一个N-M之间的随机数函数
function getRandom(N,M){
return Math.floor( Math.random()*(M-N+1))+N
}
// 2.2 生成一个随机数
let random=getRandom(0,Data.length-1)

// 3. 把对应对数据渲染到标签中
//3.1获取涂片
let img=document.querySelector('.slider-wrapper img')
//3.2修改图片路径
img.src=Data[random].url

//4 修改p中的文字
// 4.1获取p
let p=document.querySelector('.slider-footer p')
// 4.2 修改p中的内容
p.innerHTML=Data[random].title

// 5. 修改背景颜色
// 5.1获取颜色内容
let color=document.querySelector('.slider-footer')
// 5.2 修改内容
color.style.backgroundColor=Data[random].color

// 6. 小点的变化 让对应的小点添加active类
// li:nth-child(n) 能选出第n个小圆点 random 是0-7 我们要的是1-8 所以要+1
let li=document.querySelector(`.slider-indicator li:nth-child(${random+1})`)
// 让当前的li 添加类
li.classList.add('active')


</script>
</body>

</html>

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
2
3
4
5
<script>
// 每隔1s执行一次 --使用匿名函数的形式
setInterval(function(){console.log('执行');},1000)

</script>

注意:调用函数的时候不需要加()

1
2
3
4
5
6
7
8
9
10
<script>

function fun(){
console.log('执行');
}

// 写函数名原因是因为每隔一段时间他就会自动的调用
setInterval(fun,1000)

</script>

定时器返回的是一个数字,也就是当前定时器的编号

1
2
3
4
 // 定时器的返回值是一个编号
let num= setInterval(fun,1000)

console.log(num);
  • 关闭定时器

    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
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
<!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">&lt;</button>
<button class="next">&gt;</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 i=0
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')

}, 100)

</script>
</body>

</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
    8
    let btn=document.querySelector('button')
    btn.onclick=function(){
    alert("1111")
    }

    btn.onclick=function(){
    alert('ddd')

  • DOM L2.0

    事件源.addEventListener(事件, 事件处理函数)

    1
    2
    3
    btn.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">&lt;</button>
    <button class="next">&gt;</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!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>

<input type="text">

<script>
const input =document.querySelector('input')

input.addEventListener('focus',function(){
alert("获取到焦点")
})

input.addEventListener('blur',function(){
alert("失去焦点")
})
</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
    <!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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<body>

<input type="text">

<script>
const input =document.querySelector('input')

input.addEventListener('keydown',function(){
alert("键盘按下")
})

input.addEventListener('keyup',function(){
alert("键盘抬起")
})


</script>
</body>

9.6输入事件

只要用户输入内容就会触发对应的事件

想要获取用户的输入内容可以使用对象.value来获取

1
2
3
4
5
6
7
8
9
10
11
12
<body>

<input type="text">

<script>
const input =document.querySelector('input')

input.addEventListener('input',function(){
alert("输入事件")
})
</script>
</body>
  • 发布评论案例

    pl.jpg

    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
2
3
4
5
6
7
<script>
let btn=document.querySelector('button')

btn.addEventListener('click',function(e){
console.log(e);
})
</script>

9.8事件对象的常用属性

部分常用属性

  • type

    获取当前的事件类型

  • clientX/clientY

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

  • offsetX/offsetY

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

  • key

    用户按下的键盘键的值 keyCode(目前不适用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>
<input type="text" name="" id="">
<script>

let inp=document.querySelector('input')

inp.addEventListener('keyup',function(e){
console.log(e.key);

//判断是否是回车键
if(e.key='Enter'){
alert("按下了回车")
}
})
</script>
</body>
  • 案例:按下回车,发布评论

    ①:用到按下键盘事件 keydown 或者 keyup 都可以

    ②:如果用户按下的是回车键盘,则发布信息

    ③:让留言信息模块显示,把拿到的数据渲染到对应标签内部

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
<!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`

})

// 4.按下回车发布内容
// 绑定键盘事件

// 发布内容的div
let item=document.querySelector('.item')

// 内容的p
let p=document.querySelector('.text')
tx.addEventListener('keyup',function(e){
// 只有按下回车键才会触发,按下回车发布信息
if(e.key==='Enter'){
item.style.display='block'

// 获取用户输入的内容 tx.value,把用户输入的内容给p
p.innerHTML=tx.value

// 按下回车以后清空p标签中的内容
tx.value=''
}
})
</script>
</body>

</html>

9.9环境对象

指的是函数内部特殊的变量 this ,它代表着当前函数运行时所处的环境

  • 每个函数都有this环境对象,普通函数中的this指向window
1
2
3
4
5
6
7
8
9
<script>

function say(){
console.log(this);
}

say()

</script>
  • 谁调用, this 就是谁 是判断 this 指向的粗略规则

    粗略的记,谁调用函数,this就指向谁

1
2
3
4
5
6
7
8
9
10
<body>
<button>点击</button>
<script>
const btn=document.querySelector('button')

btn.addEventListener('click',function(){
console.log(this);
})
</script>
</body>

如果我们想要改变按钮的颜色,前后的两种写法

1
2
3
4
5
6
7
8
9
10
11
12
13
<body>
<button>点击</button>
<script>
const btn=document.querySelector('button')

btn.addEventListener('click',function(){
// 以往的写法,需要找到对应的对象,然后才能使用某些属性改变它的值
// btn.style.backgroundColor='red'
// 使用this的写法,谁调用this就是谁
this.style.backgroundColor='red'
})
</script>
</body>

9.10回调函数

如果将函数 A 做为参数传递给函数 B 时,我们称函数 A 为回调函数

简单理解: 当一个函数当做参数来传递给另外一个函数的时候,这个函数就是回调函数

例如,定时器, 隔一秒回过头来调用这个函数就叫做回调函数

事件监听函数:当点击按钮或者什么时候调用这个函数

回调函数示例

9.11 Tab切换

综合案例

  • 分析:

①:主要核心是类的切换, 设定一个当前类,可以让当前元素高亮

②:鼠标经过当前选项卡,先移除其余元素身上的当前类,而只给当前元素添加类,

③:注意,当前类只能有一个

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
<!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>tab栏切换</title>
<style>
* {
margin: 0;
padding: 0;
}

.tab {
width: 590px;
height: 340px;
margin: 20px;
border: 1px solid #e4e4e4;
}

.tab-nav {
width: 100%;
height: 60px;
line-height: 60px;
display: flex;
justify-content: space-between;
}

.tab-nav h3 {
font-size: 24px;
font-weight: normal;
margin-left: 20px;
}

.tab-nav ul {
list-style: none;
display: flex;
justify-content: flex-end;
}

.tab-nav ul li {
margin: 0 20px;
font-size: 14px;
}

.tab-nav ul li a {
text-decoration: none;
border-bottom: 2px solid transparent;
color: #333;
}

.tab-nav ul li a.active {
border-color: #e1251b;
color: #e1251b;
}

.tab-content {
padding: 0 16px;
}

.tab-content .item {
display: none;
}

.tab-content .item.active {
display: block;
}
</style>
</head>

<body>
<div class="tab">
<div class="tab-nav">
<h3>每日特价</h3>
<ul>
<li><a class="active" href="javascript:;">精选</a></li>
<li><a href="javascript:;">美食</a></li>
<li><a href="javascript:;">百货</a></li>
<li><a href="javascript:;">个护</a></li>
<li><a href="javascript:;">预告</a></li>
</ul>
</div>
<div class="tab-content">
<div class="item active"><img src="./images/tab00.png" alt="" /></div>
<div class="item"><img src="./images/tab01.png" alt="" /></div>
<div class="item"><img src="./images/tab02.png" alt="" /></div>
<div class="item"><img src="./images/tab03.png" alt="" /></div>
<div class="item"><img src="./images/tab04.png" alt="" /></div>
</div>
</div>


<script>
//1.给每一个a都绑定鼠标经过事件
// 1.1获取每一个a
const as=document.querySelectorAll('.tab-nav a')

// 1.2给每一a都绑定一个鼠标经过事件
for(let i=0;i<as.length;i++){
as[i].addEventListener('mouseenter',function(){
// 排他思想,干掉别人,留下自己
// 鼠标经过的时候先移除掉以前的ACitve
document.querySelector('.tab-nav .active').classList.remove('active')
// 给自己添加上类
this.classList.add('active')

// 下面的五个大盒子一一对应,其他的都排除掉,留下与i对应的那一个
document.querySelector('.tab-content .active').classList.remove('active')

// 对应序号的留下来
document.querySelector(`.tab-content .item:nth-child(${i+1})`).classList.add('active')

})
}

</script>

</body>

</html>

9.12 事件流(DOM 高级)

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

例如:要来襄阳找我学挖掘机,首先到中国,到湖北,到襄阳,到湖北文理学院理工学院这是事件的捕获,冒泡就是从里到外

事件流

9.13事件捕获

从DOM的根元素开始去执行对应的事件 (从外到里)

事件捕获需要写对应代码才能看到效果

事件捕获

addEventListener第三个参数传入 true 代表是捕获阶段触发(很少使用)

若传入false代表冒泡阶段触发,默认就是false

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="f">
父亲
<div class="s">
儿子
<div class="sz">孙子</div>
</div>
</div>
<script>
const f=document.querySelector('.f')
const s=document.querySelector('.s')
const sz=document.querySelector('.sz')

f.addEventListener('click',function(){
alert("我是爸爸")
},true)


s.addEventListener('click',function(){
alert("我是儿子")
},true)

sz.addEventListener('click',function(){
alert("我是孙子")
},true)
</script>
</body>

9.14事件冒泡

当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒跑

  • 简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件
  • 事件冒泡是一定会发生的(绑定事件的时候,第三个参数不传,就是默认允许事件冒泡)
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
<body>
<div class="f">
父亲
<div class="s">
儿子
<div class="sz">孙子</div>
</div>
</div>
<script>
const f=document.querySelector('.f')
const s=document.querySelector('.s')
const sz=document.querySelector('.sz')

f.addEventListener('click',function(){
alert("我是爸爸")
})


s.addEventListener('click',function(){
alert("我是儿子")
} )

sz.addEventListener('click',function(){
alert("我是孙子")
} )
</script>
</body>

9.15阻止事件冒泡

问题:因为默认就有冒泡模式的存在,所以容易导致事件影响到父级元素

需求:若想把事件就限制在当前元素内,就需要阻止事件冒泡

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

  • 语法

    事件冒泡

  • 注意:此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效(本质上是讲阻止流动,不仅会阻止冒泡而且会阻止捕获)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
const f=document.querySelector('.f')
const s=document.querySelector('.s')
const sz=document.querySelector('.sz')

f.addEventListener('click',function(){
alert("我是爸爸")
})


s.addEventListener('click',function(){
alert("我是儿子")
} )

sz.addEventListener('click',function(e){
alert("我是孙子")
// 阻止传播, 既能阻止冒泡也能阻止捕获
e.stopPropagation()
} )
</script>

9.16事件解绑

能给元素对象绑定事件,就能把绑定的事件解除

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
const f=document.querySelector('.f')

// 原来的绑定事件
f.onclick=function(){
alert("点击事件")
}

// 原始的解绑事件
f.onclick=null

// 目前的绑定事件
function fn(){
alert('点击事件')
}
f.addEventListener('click',fn)

// 事件的移除
f.removeEventListener('click',fn)
</script>

补充:两种注册事件的区别

  • l传统on注册(L0)

    同一个对象,后面注册的事件会覆盖前面注册(同一个事件)

    直接使用null覆盖偶就可以实现事件的解绑

    都是冒泡阶段执行的

  • 事件监听注册(L2)

    语法:addEventListener(事件类型,事件处理函数,是否使用捕获)

    后面注册的事件不会覆盖前面注册的事件(同一个事件)

    可以通过第三个参数去确定是在冒泡或者捕获阶段执行

    必须使用removeEventListener(事件类型,事件处理函数,获取捕获或者冒泡阶段)

    匿名函数无法被解绑

9.17事件委托

委托:班上的人一个人一个快递,快递小哥得给每个人送一次快递,快递小哥把快递交给班主任,班主任把快递给同学。(其中班主任可以看做父元素,每个同学可以看做子元素)

事件委托

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

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

原理:事件委托其实是利用事件冒泡的特点。

给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件

例如上面li:只需要给父元素注册一个事件,点击子元素因为有事件冒泡,所以会触发父元素的事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<body>
<ul>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
</ul>

<script>
const ul=document.querySelector('ul')
//点击子元素因为事件冒泡所以会触发父元素身上的事件
ul.addEventListener("click",function(){
alert("点击事件")
})
</script>
</body>

问题:点哪个li都能触发父元素的事件,怎么知道是哪个子元素被触发了

父元素的元素对象身上有一个target的属性,里面存放的是哪一个子元素被触发了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<body>
<ul>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
</ul>

<script>
const ul=document.querySelector('ul')
ul.addEventListener("click",function(e){

console.log(e.target);
e.target.style.color='red'
alert("点击事件")
})
</script>
</body>

问题:在父元素中,有很多的子元素,有些元素并需要触发父元素的事件,这个时候应该怎么去判断?如ul里面有li和其他的标签

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>
<ul>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<li>11111</li>
<p>我是p</p>
</ul>

<script>
const ul=document.querySelector('ul')
ul.addEventListener("click",function(e){

console.dir(e);
// target中有一个tagName的属性,就是当前的元素的名称

//只有当点击的标签的名称等于LI的时候,才添加样式
if(e.target.tagName==='LI'){
e.target.style.color='red'
}
})
</script>
</body>

9.18阻止默认行为

有些标签有默认的行为,如a标签会默认跳转,submit会自动提交,但是有些时候我们并不需要这些默认的行为,所以我们就需要取消这些默认的行为。

  • 语法:

    e.preventDefalut()

    阻止a的默认行为,阻止它的跳转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<body>

<a href="www.baidu.com">去百度</a>

<script>
const a=document.querySelector('a')

// 阻止a的默认行为
a.addEventListener('click',function(e){
// 阻止a的默认行为
e.preventDefault()
})
</script>
</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 事件

    html全部都加载完成了

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
2
3
4
5
<script>
window.addEventListener('resize',function(){
console.log('页面尺寸发生变化');
})
</script>
  • 获取元素的宽和高(不包含padding border)

获取元素的可见部分宽高(不包含边框,margin,滚动条等)

clientWidth和clientHeight

通过js来获取元素的宽度和高度

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
<!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;
}
</style>
</head>
<body>
<div>

</div>
<script>
const div=document.querySelector('div')

console.log(div.clientWidth);
</script>

</body>
</html>

9.22元素尺寸与位置尺寸

offset

  • 获取元素宽高

    Ø 获取元素的自身宽高、包含元素自身设置的宽高、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 注意是只读属性

    offset

    如果父元素没有定位,就默认是相对于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>
  • 查找兄弟节点

    1. 下一个兄弟节点

    nextElementSibling 属性

    1. 上一个兄弟节点

    previousElementSibling 属性

10.增加节点

一般情况下,我们新增节点,按照如下操作:

  • 创建一个新的节点

  • 把创建的新的节点放入到指定的元素内部

  • 创建节点

    即创造出一个新的网页元素,再添加到网页内,一般先创建节点,然后插入节点

    创建节点

  • 追加节点

    要想在界面看到,还得插入到某个父元素中

    插入到父元素的最后一个子元素:

    追加节点

    插入到父元素中某个子元素的前面

    追加节点

10.3删除节点

若一个节点在页面中已不需要时,可以删除它

  • 语法

    在 JavaScript 原生DOM操作中,要删除元素必须通过父元素删除

    删除节点

  • 注意

    如不存在父子关系则删除不成功

    删除节点和隐藏节点(display:none) 有区别的: 隐藏节点还是存在的,但是删除,则从html中删除节点

10.4综合案例:学生信息表案例

学生信息表

核心思路:

①: 声明一个空的数组

②: 点击录入,根据相关数据,生成对象,追加到数组里面

③: 根据数组数据渲染页面-表格的 行

④: 点击删除按钮,删除的是对应数组里面的数据

⑤: 再次根据数组的数据,渲染页面

步骤一:录入模块

点击录入模块

(1). 首先取消表单默认提交事件

(2). 创建新的对象,里面存储 表单获取过来的数据,格式如右图

(3). 追加给数组

(4). 渲染数据。 遍历数组, 动态生成tr, 里面填写对应td数据, 并追加给 tbody

(5). 重置表单

(6). 注意防止多次生成多条数据,先清空 tbody

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
<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')

// 所有的操作都是对数组的操作 所以需要声明一个数组
const arr = []
// 1.点击模块
// 1.1 表单提价事件
const info = document.querySelector('.info')
// 阻止表单的默认行为
info.addEventListener('submit', function (e) {
// 阻止默认行为 不跳转
e.preventDefault()

// 创建新的对象
const obj = {
// 编号
stuId: arr.length + 1,
// 姓名
uname: uname.value,
// 年龄
age: age.value,
// 性别
gender: gender.value,
// 工资
salary: salary.value,
// 城市
city: city.value
}

// 把对象追加给数组
arr.push(obj)

// 清空表单 c重置表单
info.reset()

// 调用渲染函数
xr()

})


// 2.渲染函数 因为增加和删除都需要渲染
function xr () {

tbody.innerHTML = ''


// 遍历数组

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>
`

// 将tr添加到父元素tbody中
tbody.appendChild(tr)

}



}
  • 点击删除模块

点击删除模块

(1). 采用事件委托形式,给 tbody 注册点击事件

(2). 点击链接,要删除的是对应数组里面的这个数据,而不是删除dom节点,如何找到这个数据?

(3). 前面渲染数据的时候,动态给a链接添加 自定义属性 data-id=“0”,这样点击当前对象就知道索引号了

(4). 根据索引号,利用 splice 删除这条数据

(5). 重新渲染

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
<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')

// 所有的操作都是对数组的操作 所以需要声明一个数组
const arr = []
// 1.点击模块
// 1.1 表单提价事件
const info = document.querySelector('.info')
// 阻止表单的默认行为
info.addEventListener('submit', function (e) {
// 阻止默认行为 不跳转
e.preventDefault()

// 创建新的对象
const obj = {
// 编号
stuId: arr.length + 1,
// 姓名
uname: uname.value,
// 年龄
age: age.value,
// 性别
gender: gender.value,
// 工资
salary: salary.value,
// 城市
city: city.value
}

// 把对象追加给数组
arr.push(obj)

// 清空表单 c重置表单
info.reset()

// 调用渲染函数
xr()

})


// 2.渲染函数 因为增加和删除都需要渲染
function xr () {

tbody.innerHTML = ''


// 遍历数组

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>
`

// 将tr添加到父元素tbody中
tbody.appendChild(tr)

}



}


// 删除事件 使用事件委托,如果用户点击的是a就删除

tbody.addEventListener('click', function (e) {
if (e.target.tagName === 'A') {

// 获取的是第几个数据
// e.target.dataset.id 能拿到对应的id
// 删除对应的数据

arr.splice(e.target.dataset.id, 1)
// 重新渲染
xr()
}
})
</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
    8
    console.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 地址,对其赋值时用于地址的跳转

    localtion

  • 案例:

    案例

    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 属性获取地址中携带的参数,符号 ?后面部分

    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 时表示强制刷新

    loca

  • 总结

    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的常用的方法

history

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<body>


<a href="https://www.baidu.com/">百度</a>
<button>前进</button>
<button class="bk">后退</button>

<script>

const go=document.querySelector("button")
go.addEventListener('click',function(){
history.go(1)
})

const back=document.querySelector(".bk")

back.addEventListener('click',function(){
history.back()
})

</script>
</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
2
3
4
5
6
7
8
9
10
11
<script>
const obj={
name:"张三",
age:100,
love:"吃饭"
}
// 存储复杂的数据类型
localStorage.setItem('obj',obj)

console.log(localStorage.getItem(obj));
</script>

存储复杂数据类型必须转化为JSON字符串存储

JSON.stringify(复杂数据类型):将复杂的数据类型转化为JSON类型的字符串

1
2
3
4
5
6
7
8
9
10
11
<script>
const obj={
name:"张三",
age:100,
love:"吃饭"
}
//将复杂的数据类型转化成为json类型的数据
localStorage.setItem('obj',JSON.stringify(obj))

console.log(localStorage.getItem(obj));
</script>

存储进去的是JSON类型的字符串,取出来也是JSON类型的字符串

使用的时候需要将JSON类型的数据转化成为对象

**语法:JSON.parse(JSON字符串)**:把JSON字符串转换为对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
const obj={
name:"张三",
age:100,
love:"吃饭"
}
// 存储复杂的数据类型
localStorage.setItem('obj',JSON.stringify(obj))

let myobj=localStorage.getItem('obj')

// 将JSON转化成为对象类型的数据
console.log( JSON.parse(myobj));
</script>

12.正则表达式

正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象

  • 作用

    例如验证表单:用户名表单只能输入英文字母、数字或者下划线, 昵称输入框中可以输入中文(匹配)比如用户名: /^[a-z0-9_-]{3,16}$/

    Ø 过滤掉页面内容中的一些敏感词(替换),

    从字符串中获取我们想要的特定部分(提取)等 。

  • 语法

    我们想要查找是否有戴眼镜的人, 怎么做呢?

    1. 定义规则: 戴眼镜的

    2. 根据规则去查找:找到则返回

    正则同样道理,我们分为两步:

    1. 定义规则

    2. 查找

    戴眼镜

    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>