JavaScript 学习笔记 超详细(b站pink老师)
权威网站: MDN
JavaScript权威网站: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript
目录
一、JavaScript基础
1.JavaScript介绍
1.1 JavaScript 是什么
1.2 JavaScript 书写位置
1.3 JavaScript 注释
1.4 JavaScript 结束符
1.5 JavaScript 输入输出语法
1.6 字面量
2.变量
2.1 变量是什么?
2.2 变量的基本使用
2.3 变量的本质
2.4 变量命名规则与规范
2.5变量拓展-let和var的区别
2.6变量拓展-数组
3.常量
4.数据类型
4.1 数据类型 – 数字类型(Number)
4.2 数据类型 – 字符串类型(string)
4.3数据类型 – 布尔类型(boolean)
4.4数据类型 – 未定义类型(undefined)
4.5数据类型 – null(空类型)
4.6控制台输出语句和检测数据类型
5.类型转换
5.1 为什么需要类型转换
5.2 隐式转换
5.3 显式转换
综合案例:用户订单信息案例
6.运算符
6.1 赋值运算符
6.2 一元运算符
6.3 比较运算符
6.4 逻辑运算符
6.5 运算符优先级
7.语句
7.1 表达式语句
7.2 分支语句( if语句、三元运算符、switch语句 )
7.3 循环结构
综合案例:简易ATM取款机案例
8.for循环
9.数组
9.1 数组是什么
9.2 数组的基本使用
9.3 操作数组
综合案例:根据数据生成柱形图
9.4 冒泡排序
9.5 数组排序
10.函数
10.1 为什么需要函数
10.2 函数使用
10.3 函数传参
10.4 函数返回值
10.5 函数细节补充
10.6 作用域
10.7 匿名函数
综合案例:转换时间案例
10.8 逻辑中断
10.对象
10.1 对象是什么
10.2 对象使用
10.2 对象使用
10.3 遍历对象
10.4 内置对象
综合案例:学成在线页面渲染案例
拓展-术语解释
拓展- 基本数据类型和引用数据类型
拓展- 变量声明
二、Web APIs
1. Web API 基本认知
1.1 作用和分类
1.2 什么是DOM
1.3 DOM树
1.4 DOM对象(重要)
2.获取DOM对象
2.1 根据CSS选择器来获取DOM元素 (重点)
2.2 其他获取DOM元素方法(了解)
3. 操作元素内容
4.操作元素属性
4.1 操作元素常用属性
4.2 操作元素样式属性
案例:轮播图随机版
4.3 操作表单元素属性
4.4 自定义属性
5.定时器-间歇函数
综合案例:轮播图定时器版
6.事件监听(绑定)
6.1 事件监听
6.2 事件监听版本
7.事件类型
案例:轮播图完整版
8.事件对象
8.1 获取事件对象
8.2 事件对象常用属性
9.环境对象
10.回调函数
综合案例:Tab栏切换
重点案例:全选文本框
11.事件流
11.1 事件流和两个阶段说明
11.2 事件捕获
11.3 事件冒泡
11.4 阻止冒泡
11.5 解绑事件
拓展:鼠标经过事件的区别、两种注册事件的区别
12.事件委托
案例:tab栏切换改造
13.其他事件
13.1 页面加载事件
13.2 页面滚动事件
13.3 页面尺寸事件
13.4 元素尺寸与位置
总结
综合案例:电梯导航
14. 日期对象
一、JavaScript基础
1.JavaScript介绍
1.1 JavaScript 是什么
1. JavaScript (是什么?)
是一种运行在客户端(浏览器)的编程语言,实现人机交互效果。
2. 作用(做什么?)
– 网页特效 (监听用户的一些行为让网页作出对应的反馈)
– 表单验证 (针对表单数据的合法性进行判断)
– 数据交互 (获取后台的数据, 渲染到前端)
– 服务端编程 (node.js)
3. JavaScript的组成(有什么?)
● ECMAScript: 规定了js基础语法核心知识。
比如:变量、分支语句、循环语句、对象等等
● Web APIs :
- DOM 操作文档,比如对页面元素进行移动、大小、添加删除等操作
- BOM 操作浏览器,比如页面弹窗,检测窗口宽度、存储数据到浏览器等等
1.2 JavaScript 书写位置
1. 内部 JavaScript
直接写在html文件里,用script标签包住
规范:script标签写在</body>上面
<body><!-- 内部 --><script>alert('努力,奋斗');</script>
</body>
注意事项:
将<script>放在HTML文件的底部附近的原因是浏览器会按照代码在文件中的顺序加载HTML。
如果先加载的JavaScript期望修改其下方 HTML,那么它可能由于HTML尚未被加载而失效。
因此,将JavaScript代码放在HTM页面的底部附近通常是最好的策略。
2. 外部 JavaScript
代码写在以.js结尾的文件里
语法:通过script标签,引入到html页面中。
<body><!-- 外部 --><script src="./js/my.js"></script>
</body>
注意事项:
1. script标签中间无需写代码,否则会被忽略!
2. 外部JavaScript会使代码更加有序,更易于复用,且没有了脚本的混合,HTML也会更加易读,因此这是个好的习惯。
3. 内联 JavaScript
代码写在标签内部
语法:
<body><button onclick="alert('努力,奋斗')">点击</button>
</body>
1.3 JavaScript 注释
● 单行注释(//)
作用://右边这一行的代码会被忽略
快捷键:ctrl + /
● 块注释(/* */)
作用:在/* 和 */ 之间的所有内容都会被忽略
快捷键:shift + alt + A
1.4 JavaScript 结束符
● 结束符
作用: 使用英文的 ; 代表语句结束
实际情况: 实际开发中,可写可不写, 浏览器(JavaScript引擎)可以自动推断语句的结束位置
现状: 在实际开发中,越来越多的人主张,书写JavaScript代码时省略结束符
约定:为了风格统一,结束符要么每句都写,要么每句都不写(按照团队要求)
1.5 JavaScript 输入输出语法
输出和输入也可理解为人和计算机的交互,用户通过键盘、鼠标等向计算机输入信息,计算机处理后再展示结果给用户,这便是一次输入和输出的过程。
1.输出语法:
语法1:
作用:向body内输出内容
注意:如果输出的内容写的是标签,也会被解析成网页元素,如:
语法2:
作用:页面弹出警告对话框
语法3:
作用:控制台输出语法,程序员调试使用
2. 输入语法:
语法:
作用:显示一个对话框,对话框中包含一条文字信息,用来提示用户输入文字
3.JavaScript 代码执行顺序:
按HTML文档流顺序执行JavaScript代码
alert() 和 prompt() 它们会跳过页面渲染先被执行
1.6 字面量
在计算机科学中,字面量(literal)是在计算机中描述 事/物
比如:
我们工资是: 8000 此时8000就是数字字面量;'黑马程序员' 字符串字面量;还有接下来学的 [] 数组字面量 {} 对象字面量 等等
2.变量
2.1 变量是什么?
变量:
● 白话:变量就是一个装东西的盒子。
● 通俗:变量是计算机中用来存储数据的“容器”,它可以让计算机变得有记忆。
● 注意:变量不是数据本身,它们仅仅是一个用于存储数值的容器。可以理解为是一个个用来装东西的纸箱子。
2.2 变量的基本使用
1. 声明变量:
要想使用变量,首先需要创建变量(也称为声明变量或者定义变量)
语法:
声明变量有两部分构成:声明关键字、变量名(标识)
let 即关键字 (let: 允许、许可、让),所谓关键字是系统提供的专门用来声明(定义)变量的词语
举例:let age
我们声明了一个age变量,age 即变量的名称,也叫标识符
2. 变量赋值:
定义了一个变量后,就能够初始化它(赋值)。在变量名之后跟上一个“=”,然后是数值。
注意:是通过变量名来获得变量里面的数据
简单点,也可以声明变量的时候直接完成赋值操作,这种操作也称为 变量初始化。
3. 更新变量:
变量赋值后,还可以通过简单地给它一个不同的值来更新它。
注意: let 不允许多次声明一个变量。
4. 声明多个变量:
变量赋值后,还可以通过简单地给它一个不同的值来更新它。
语法:多个变量中间用逗号隔开。
说明:看上去代码长度更短,但并不推荐这样。为了更好的可读性,请一行只声明一个变量。
变量案例:交换变量的值
核心思路:使用一个临时变量temp用来做中间存储。
<body><script>let num1 = 'pink老师'let num2 = '周深'let temp// 都是把右边给左边temp = num1num1 = num2num2 = tempconsole.log(num1, num2)</script>
</body>
2.3 变量的本质
内存:计算机中存储数据的地方,相当于一个空间
变量本质:是程序在内存中申请的一块用来存放数据的小空间
2.4 变量命名规则与规范
规则:必须遵守,不遵守报错 (法律层面)
规范:建议,不遵守不会报错,但不符合业内通识 (道德层面)
1. 规则:
不能用关键字。关键字:有特殊含义的字符,JavaScript内置的一些英语词汇。例如:let、var、if、for等
只能用下划线、字母、数字、$组成,且数字不能开头
字母严格区分大小写,如Age和age是不同的变量
2. 规范:
起名要有意义
遵守小驼峰命名法
第一个单词首字母小写,后面每个单词首字母大写。例:userName、myFirstName
2.5变量拓展-let和var的区别
let 和 var 区别:
在较旧的JavaScript,使用关键字 var 来声明变量 ,而不是 let。
var 现在开发中一般不再使用它,只是我们可能再老版程序中看到它。
let 为了解决 var 的一些问题。
var 声明:
○ 可以先使用 在声明 (不合理)
○ var 声明过的变量可以重复声明(不合理)
○ 比如变量提升、全局变量、没有块级作用域等等
结论:以后声明变量统一使用 let
2.6变量拓展-数组
● 数组 (Array) —— 一种将一组数据存储在单个变量名下的优雅方式
2.6.1 数组的基本使用
1. 声明语法:let 数组名 = [数据1, 数据2, ..., 数据n]
○ 数组是按顺序保存,所以每个数据都有自己的编号
○ 计算机中的编号从0开始,第二个数据编号为1,以此类推
○ 在数组中,数据的编号也叫索引或下标
○ 数组可以存储任意类型的数据
2.取值语法:数组名[下标]
通过下标取数据。取出来是什么类型的,就根据这种类型特点来访问。
3.一些术语:
● 元素:数组中保存的每个数据都叫数组元素
● 下标:数组中数据的编号
● 长度:数组中数据的个数,通过数组的length属性获得
let arr = ['刘德华', '张学友', '黎明', '郭富城', 'pink老师', 10]
console.log(arr.length) // 6
3.常量
概念:使用 const 声明的变量称为“常量”。
使用场景:当某个变量永远不会改变的时候,就可以使用 const 来声明,而不是let。
命名规范:和变量一致
常量使用:
// 1.常量 不允许更改值const PI = 3.14console.log(PI)
注意: 常量不允许重新赋值,声明的时候必须赋值(初始化)
小技巧:不需要重新赋值的数据使用const
const — 类似于 let ,但是变量的值无法被修改。
4.数据类型
JS 数据类型整体分为两大类:
● 基本数据类型
● 引用数据类型
4.1 数据类型 – 数字类型(Number)
即我们数学中学习到的数字,可以是整数、小数、正数、负数。
JavaScript 中的正数、负数、小数等 统一称为 数字类型。
注意事项:
JS是弱数据类型,变量属于哪种类型,只有赋值之后我们才能确认
Java是强数据类型 例如 int a = 3 必须是整数
数字可以有很多操作,比如,乘法 * 、除法 / 、加法 + 、减法 - 等等,所以经常和算术运算符一起。
数学运算符也叫算术运算符,主要包括加、减、乘、除、取余(求模)。
➱ +:求和
➱ -:求差
➱ *:求积
➱ /:求商
➱ %:取模(取余数),开发中经常作为某个数字是否被整除
同时使用多个运算符编写程序时,会按着某种顺序先后执行,我们称为优先级。
JavaScript中优先级越高越先被执行,优先级相同时以书从左向右执行。
● 总结: 先乘除取余,后加减,有小括号先算小括号里面的
NaN 代表一个计算错误。它是一个不正确的或者一个未定义的数学操作所得到的结果。
NaN 是粘性的。任何对 NaN 的操作都会返回 NaN
4.2 数据类型 – 字符串类型(string)
通过单引号( '') 、双引号( "")或反引号( ` ) 包裹的数据都叫字符串,单引号和双引号没有本质上的区别,推荐使用单引号。
注意事项:
1. 无论单引号或是双引号必须成对使用
2. 单引号/双引号可以互相嵌套,但是不以自已嵌套自已(口诀:外双内单,或者外单内双)
3. 必要时可以使用转义符 \,输出单引号或双引号
字符串拼接
场景: + 运算符 可以实现字符串的拼接。
口诀:数字相加,字符相连
let age = 25document.write('我今年' + age + '岁了')
模板字符串
使用场景:拼接字符串和变量
在没有它之前,要拼接变量比较麻烦
语法:`` (反引号) 在英文输入模式下按键盘的tab键上方那个键(1左边那个键)。内容拼接变量时,用 ${ } 包住变量
<script>// // 模板字符串 外面用`` 里面 ${变量名}let uname = prompt('请输入您的姓名:')let age = prompt('请输入您的年龄:')document.write(`大家好,我叫${uname}, 我今年贵庚${age}岁了`)</script>
4.3数据类型 – 布尔类型(boolean)
表示肯定或否定时在计算机中对应的是布尔类型数据。
它有两个固定的值true和false,表示肯定的数据用true(真),表示否定的数据用false(假)。
4.4数据类型 – 未定义类型(undefined)
未定义是比较特殊的类型,只有一个值undefined。
什么情况出现未定义类型?
只声明变量,不赋值的情况下,变量的默认值为undefined,一般很少直接为某个变量赋值为undefined。
// 未定义类型 弱数据类型 声明一个变量未赋值就是 undefinedlet numconsole.log(num)
工作中的使用场景:
我们开发中经常声明一个变量,等待传送过来的数据。如果我们不知道这个数据是否传递过来,此时我们可以通过检测这个变量是不是undefined,就判断用户是否有数据传递过来。
4.5数据类型 – null(空类型)
JavaScript 中的 null 仅仅是一个代表“无”、“空”或“值未知”的特殊值
// null 空的let obj = nullconsole.log(obj)
null 和 undefined 区别:
● undefined 表示没有赋值
● null 表示赋值了,但是内容为空
// 计算有区别console.log(undefined + 1) // NaNconsole.log(null + 1) // 1
null 开发中的使用场景:
官方解释:把null作为尚未创建的对象
通俗解释:将来有个变量里面存放的是一个对象,但是对象还没创建好,可以先给个null
4.6控制台输出语句和检测数据类型
1.控制台输出语句:
控制台语句经常用于测试结果来使用。
数字型和布尔型颜色为蓝色,字符串和undefined颜色为灰色
2. 通过 typeof 关键字检测数据类型
typeof 运算符可以返回被检测的数据类型。它支持两种语法形式:
1. 作为运算符: typeof x (常用的写法)
2. 函数形式: typeof(x)
换言之,有括号和没有括号,得到的结果是一样的,所以我们直接使用运算符的写法。
5.类型转换
5.1 为什么需要类型转换
JavaScript是弱数据类型: JavaScript也不知道变量到底属于那种数据类型,只有赋值了才清楚。
坑:使用表单、prompt 获取过来的数据默认是字符串类型的,此时不能直接进行加法运算。
此时需要转换变量的数据类型。
通俗来说,就是把一种数据类型的变量转换成我们需要的数据类型。
5.2 隐式转换
某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换称为隐式转换。
规则:
1. + 号两边只要有一个是字符串,都会把另外一个转成字符串
console.log('pink' + 1) // pink1console.log(2 + 2) // 4console.log(2 + '2') // 22
2. 除了+以外的算术运算符 比如 - * / 等都会把数据转成数字类型
console.log(2 - 2) // 0console.log(2 - '2') // 0
缺点: 转换类型不明确,靠经验才能总结
小技巧:
1. +号作为正号解析可以转换成数字型
console.log(+'123') // 转换为数字型 123
2.任何数据和字符串相加结果都是字符串
5.3 显式转换
编写程序时过度依靠系统内部的隐式转换是不严禁的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。为了避免因隐式转换带来的问题,通常根逻辑需要对数据进行显示转换。
概念: 自己写代码告诉系统该转成什么类型
转换为数字型有三种方法:
● Number(数据)
转成数字类型
如果字符串内容里有非数字,转换失败时结果为NaN(Not a Number)即不是一个数字
NaN也是number类型的数据,代表非数字
● parseInt(数据) 只保留整数
● parseFloat(数据) 可以保留小数
转换为字符型:
● String(数据)
● 变量.toString(进制)
综合案例:用户订单信息案例
<!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>h2 {text-align: center;}table,th,td {border: 1px solid #000;}table {/* 合并相邻边框 */border-collapse: collapse;text-align: center;height: 80px;margin: 0 auto;}th {padding: 10px 30px;}</style>
</head>
<body><h2>订单确认</h2><script>let price = +prompt('请输入商品价格:')let num = +prompt('请输入商品数量:')let address = prompt('请输入收货地址:')let total = price * numdocument.write(`<table><thead><th>商品名称</th><th>商品价格</th><th>商品数量</th><th>总价</th><th>收货地址</th></thead><tbody><tr><td>小米手机青春PLUS</td><td>${price}元</td><td>${num}</td><td>${total}元</td><td>${address}</td></tr></tbody></table>`)</script>
</body>
</html>
6.运算符
6.1 赋值运算符
赋值运算符(=):对变量进行赋值的运算符
= 将等号右边的值赋予给左边, 要求左边必须是一个容器
其他赋值运算符: += 、-= 、*= 、/= 、%=
使用这些运算符可以在对变量赋值时进行快速操作
6.2 一元运算符
众多的JavaScript的运算符可以根据所需表达式的个数,分为一元运算符、二元运算符、三元运算符。
● 自增(++)
作用:让变量的值 +1
● 自减(--)
作用:让变量的值 -1
● 使用场景:经常用于计数来使用。 比如进行10次操作,用它来计算进行了多少次了
● 自增运算符的用法:
前置自增: 后置自增:
前置自增和后置自增的区别:
前置自增:先自加再使用(记忆口诀:++在前 先加)
后置自增:先使用再自加(记忆口诀:++在后 后加)
注意:
1. 前置自增和后置自增独立使用时二者并没有差别!
2. 实际开发中,我们一般都是单独使用的,后置自增会使用相对较多
拓展:
输出7
6.3 比较运算符
使用场景:比较两个数据大小、是否相等
>: 左边是否大于右边
<: 左边是否小于右边
>=: 左边是否大于或等于右边
<=: 左边是否小于或等于右边
==: 左右两边值是否相等
===: 左右两边是否类型和值都相等
!==: 左右两边是否不全等
比较运算符有隐式转换。比较结果为boolean类型,即只会得到true或false。
= 和 == 和 === 对比:
● = 单等是赋值
● == 是判断
● === 是全等
开发中判断是否相等,强烈推荐使用 ===
● 字符串比较,是比较的字符对应的ASCII码
从左往右依次比较,如果第一位一样再比较第二位,以此类推
● NaN不等于任何值,包括它本身,涉及到NaN都是false
● 尽量不要比较小数,因为小数有精度问题
● 不同类型之间比较会发生隐式转换
最终把数据隐式转换转成number类型再比较
所以开发中,如果进行准确的比较我们更喜欢 === 或者 !==
6.4 逻辑运算符
表达式1 && 表达式2:表达式1为真,返回表达式2;表达式1为假,返回表达式1
表达式1 || 表达式2:表达式1为真,返回表达式1;表达式1为假,返回表达式2
6.5 运算符优先级
一元运算符里面的逻辑非优先级很高。逻辑与比逻辑或优先级高。
7.语句
7.1 表达式语句
● 表达式:表达式是可以被求值的代码,JavaScript 引擎会将其计算出一个结果。
● 语句:语句是一段可以执行的代码。比如:prompt()可以弹出一个输入框,还有if语句、for循环语句等等
区别:
表达式:因为表达式可被求值,所以它可以写在赋值语句的右侧。如:num = 3 + 4
语句:而语句不一定有值,所以比如alert()、for和break等语句就不能被用于赋值。
7.2 分支语句( if语句、三元运算符、switch语句 )
程序三大流程控制语句
● 以前我们写的代码,写几句就从上往下执行几句,这种叫顺序结构
● 有的时候要根据条件选择执行代码,这种就叫分支结构
● 某段代码被重复执行,就叫循环结构
● 分支语句可以让我们有选择性的执行想要的代码
● 分支语句包含:if分支语句、三元运算符、switch语句
7.2.1 if语句
if语句有三种使用:单分支、双分支、多分支
● 单分支 if 语法:
括号内的条件为true时,进入大括号里执行代码;小括号内的结果若不是布尔类型时,会发生隐式转换转为布尔类型。除了0 所有的数字都为真,除了''所有的字符串都为真true
如果大括号只有一个语句,大括号可以省略,但是不提倡这么做
● 双分支 if 语法:
● 多分支 if 语法:
使用场景:适合于有多个结果的时候,比如学习成绩可以分为: 优 良 中 差
先判断条件1,若满足条件1就执行代码1,其他不执行;若不满足则向下判断条件2,满足条件2执行代码2,其他不执行;若依然不满足继续往下判断,依次类推;若以上条件都不满足,执行else里的代码n
7.2.2 三元运算符
使用场景: 其实是比if双分支更简单的写法,可以使用 三元表达式,一般用来取值
符号:? 与 : 配合使用
语法:
数字补0案例
用户输入1个数,如果数字小于10,则前面进行补0, 比如09
<script>// 1. 用户输入 let num = prompt('请您输入一个数字:')// 2. 判断输出- 小于10才补0num = num < 10 ? 0 + num : numalert(num)</script>
7.2.3 switch语句
语法:
释义:
找到跟小括号里数据全等的case值,并执行里面对应的代码,例:数据若跟值2全等,则执行代码2;若没有全等 === 的则执行default里的代码
注意事项:
1. switch case语句一般用于等值判断,不适合于区间判断
2. switch case一般需要配合break关键字使用,没有break会造成case穿透
简单计算器案例
<script>// 1.用户输入 2个数字 + 操作符号 + - * / let num1 = +prompt('请您输入第一个数字:')let num2 = +prompt('请您输入第二个数字:')let sp = prompt('请您输入 + - * / 其中一个:')// 2. 判断输出switch (sp) {case '+':alert(`两个数的加法操作是${num1 + num2}`)breakcase '-':alert(`两个数的减法操作是${num1 - num2}`)breakcase '*':alert(`两个数的乘法操作是${num1 * num2}`)breakcase '/':alert(`两个数的除法操作是${num1 / num2}`)breakdefault:alert(`请输入+-*/`)} </script>
7.3 循环结构
7.3.1 断点调试
作用:学习时可以帮助更好的理解代码运行,工作时可以更快找到bug
浏览器打开调试界面
1. 按F12打开开发者工具
2. 点到sources一栏
3. 选择代码文件,添加断点并刷新
断点:在某句代码上加的标记就叫断点,当程序执行到这句有标记的代码时会停下来
7.3.2 while 循环
while循环就是在满足条件期间,重复执行某些代码。
1. while 循环基本语法:
释义:
跟if语句很像,都要满足小括号里的条件为true才会进入循环体执行代码。while大括号里代码执行完毕后不会跳出,而是继续回到小括号里判断条件是否满足,若满足又执行大括号里的代码,然后再回到小括号判断条件,直到括号内条件不满足,即跳出。
2. while 循环三要素:
循环的本质就是以某个变量为起始值,然后不断产生变化量,慢慢靠近终止条件的过程。
所以,while循环需要具备三要素:
1. 变量起始值
2. 终止条件(没有终止条件,循环会一直执行,造成死循环)
3. 变量变化量(用自增或者自减)
3 循环退出
循环结束:
● break:退出循环
● continue:结束本次循环,继续下次循环
区别:
● continue退出本次循环,一般用于排除或者跳过某一个选项的时候, 可以使用continue
● break退出整个循环,一般用于结果已经得到, 后续的循环不需要的时候可以使用
综合案例:简易ATM取款机案例
<script>// 1. 开始循环 输入框写到 循环里面// 3. 准备一个总的金额let money = 100while (true) {let re = +prompt(`请您选择操作:1.存钱2.取钱3.查看余额4.退出`)// 2. 如果用户输入的 4 则退出循环, break 写到if 里面,没有写到switch里面, 因为4需要break退出循环if (re === 4) {break}// 4. 根据输入做操作switch (re) {case 1:// 存钱let cun = +prompt('请输入存款金额')money = money + cunbreakcase 2:// 存钱let qu = +prompt('请输入取款金额')money = money - qubreakcase 3:// 存钱alert(`您的银行卡余额是${money}`)break}}</script>
8.for循环
1. for循环语法
作用:重复执行代码
好处:把声明起始值、循环条件、变化值写到一起,让人一目了然,它是最常使用的循环形式
2. 退出循环
● continue退出本次循环,一般用于排除或者跳过某一个选项的时候,可以使用continue
● break退出整个for循环,一般用于结果已经得到, 后续的循环不需要的时候可以使用
了解:
1. while(true) 来构造“无限”循环,需要使用break退出循环。
2. for(;;) 也可以来构造“无限”循环,同样需要使用break退出循环。
for循环和while循环的区别:
● 当如果明确了循环的次数的时候推荐使用for循环
● 当不明确循环的次数的时候推荐使用while循环
3. for 循环嵌套:一个循环里再套一个循环,一般用在for循环里
案例:九九乘法表
<script>// 1. 外层循环控制行数for (let i = 1; i <= 9; i++) {// 2. 里层循环控制列数for (let j = 1; j <= i; j++) {document.write(`<span>${j} X ${i} = ${i * j}</span>`)}// 换行document.write('<br>')}</script>
9.数组
9.1 数组是什么
9.2 数组的基本使用
数组是按顺序保存,所以每个数据都有自己的编号
计算机中的编号从0开始,所以小明的编号为0,小刚编号为1,以此类推
在数组中,数据的编号也叫索引或下标
数组可以存储任意类型的数据
9.3 操作数组
操作数组-新增
操作数组-删除
arr. pop() 方法从数组中删除最后一个元素,并返回该元素的值
语法:arr.pop()
数组. splice() 方法 删除指定元素
语法:数组.splice(start, deleteCount, item1, item2, ..., itemN)
从start开始删除deleteCount个数组元素,并从start处开始添加item(item可加可不加)
语法:
综合案例:根据数据生成柱形图
<!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 {display: flex;width: 700px;height: 300px;border-left: 1px solid pink;border-bottom: 1px solid pink;margin: 100px auto;justify-content: space-around;align-items: flex-end;text-align: center;}.box>div {display: flex;width: 50px;background-color: pink;flex-direction: column;justify-content: space-between;}.box div span {margin-top: -20px;}.box div h4 {margin-bottom: -35px;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)arr.push(prompt(`请输入第${i}季度的数据:`))// push记得加小括号,不是等号赋值的形式}// console.log(arr) ['123','135','345','234']// 盒子开头document.write(` <div class="box">`)// 盒子中间 利用循环的形式 跟数组有关系for (let i = 0; i < arr.length; i++) {document.write(`<div style="height: ${arr[i]}px;"><span>${arr[i]}</span><h4>第${i + 1}季度</h4></div> `)}// 盒子结尾document.write(` </div>`)</script>
</body></html>
9.4 冒泡排序
9.5 数组排序
let arr = [4, 2, 5, 1, 3]
// 1.升序排列写法
arr.sort(function (a, b) {
return a - b
})
console.log(arr) // [1, 2, 3, 4, 5]
// 降序排列写法
arr.sort(function (a, b) {
return b - a
})
console.log(arr) // [5, 4, 3, 2, 1]
10.函数
10.1 为什么需要函数
10.2 函数使用
函数的调用语法:函数名()
我们曾经使用的 alert() , parseInt() 这种名字后面跟小括号的本质都是函数的调用
10.3 函数传参
这个默认值只会在缺少实参参数传递时才会被执行,所以有参数会优先执行传递过来的实参, 否则默认为undefined
10.4 函数返回值
10.5 函数细节补充
10.6 作用域
在JavaScript中,根据作用域的不同,变量可以分为:
作用域链:采取就近原则的方式来查找变量最终的值
<script>let a = 1function fn1() {let a = 2let b = '22'fn2()function fn2() {let a = 3fn3()function fn3() {let a = 4console.log(a) //a的值 ?console.log(b) //b的值 ?}}}fn1()</script>
a 的值为4,b的值为 ‘22’
10.7 匿名函数
注意: 多个立即执行函数要用 ; 隔开,要不然会报错
综合案例:转换时间案例
<script>// 1. 用户输入let second = +prompt('请输入秒数:')// 2.封装函数function getTime(t) {// 3. 转换 let h = parseInt(t / 60 / 60 % 24)let m = parseInt(t / 60 % 60)let s = parseInt(t % 60)h = h < 10 ? '0' + h : hm = m < 10 ? '0' + m : ms = s < 10 ? '0' + s : sreturn `转换完毕之后是${h}小时${m}分${s}秒`}let str = getTime(second)document.write(str)</script>
10.8 逻辑中断
表达式1 && 表达式2:表达式1为真,返回表达式2;表达式1为假,返回表达式1
表达式1 || 表达式2:表达式1为真,返回表达式1;表达式1为假,返回表达式2
10.对象
10.1 对象是什么
10.2 对象使用
1. 对象声明语法
10.2 对象使用
对象本质是无序的数据集合, 操作数据无非就是 增 删 改 查
查询对象:
1. 对象名.属性
10.3 遍历对象
<!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><!-- script写到这里 --><script>// 1. 数据准备let students = [{ name: '小明', age: 18, gender: '男', hometown: '河北省' },{ name: '小红', age: 19, gender: '女', hometown: '河南省' },{ name: '小刚', age: 17, gender: '男', hometown: '山西省' },{ name: '小丽', age: 18, gender: '女', hometown: '山东省' },{ name: '晓强', age: 16, gender: '女', hometown: '蓝翔技校' }]// 2. 渲染页面for (let i = 0; i < students.length; i++) {document.write(`<tr><td>${i + 1}</td><td>${students[i].name}</td><td>${students[i].age}</td><td>${students[i].gender}</td><td>${students[i].hometown}</td></tr>`)}</script></table></body></html>
10.4 内置对象
1.内置对象是什么?
<script>// 1. 随机生成一个数字 1~10// 取到 N ~ M 的随机整数function getRandom(N, M) {return Math.floor(Math.random() * (M - N + 1)) + N}let random = getRandom(1, 10)// 2. 设定三次 三次没猜对就直接退出let flag = true // 开关变量 for (let i = 1; i <= 3; i++) {let num = +prompt('请输入1~10之间的一个数字:')if (num > random) {alert('您猜大了,继续')} else if (num < random) {alert('您猜小了,继续')} else {flag = falsealert('猜对了,真厉害')break}}// 写到for的外面来if (flag) {alert('次数已经用完')}</script>
案例:生成随机颜色
<script>// 1. 自定义一个随机颜色函数function getRandomColor(flag = true) {if (flag) {// 3. 如果是true 则返回 #fffffflet str = '#'let arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']// 利用for循环随机抽6次 累加到 str里面for (let i = 1; i <= 6; i++) {// 每次要随机从数组里面抽取一个 // random 是数组的索引号 是随机的let random = Math.floor(Math.random() * arr.length)str += arr[random]}return str} else {// 4. 否则是 false 则返回 rgb(255,255,255)let r = Math.floor(Math.random() * 256) // 255let g = Math.floor(Math.random() * 256) // 255let b = Math.floor(Math.random() * 256) // 255return `rgb(${r},${g},${b})`}}// 2. 调用函数 getRandomColor(布尔值)console.log(getRandomColor(false))console.log(getRandomColor(true))console.log(getRandomColor())</script>
综合案例:学成在线页面渲染案例
<!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><!-- 4. box核心内容区域开始 --><div class="box w"><div class="box-hd"><h3>精品推荐</h3><a href="#">查看全部</a></div><div class="box-bd"><ul class="clearfix"><!-- <li><a href="#"><img src="data:images/course01.png" alt=""><h4>Think PHP 5.0 博客系统实战项目演练</h4><div class="info"><span>高级</span> • <span>1125</span>人在学习</div></a></li> --><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: 'AndroidAPP实战项目演练',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},{src: 'images/course04.png',title: '自动添加的模块',num: 1000}]for (let i = 0; i < data.length; i++) {document.write(`<li><a href="#"><img src=${data[i].src} title="${data[i].title}"><h4>${data[i].title}</h4><div class="info"><span>高级</span> • <span>${data[i].num}</span>人在学习</div></a></li>`)}</script></ul></div></div></body></html>
附:style.css
* {margin: 0;padding: 0;
}
.w {width: 1200px;margin: auto;
}
body {background-color: #f3f5f7;
}
li {list-style: none;
}
a {text-decoration: none;
}
.clearfix:before,.clearfix:after {content:"";display:table; }.clearfix:after {clear:both;}.clearfix {*zoom:1;} .box {margin-top: 30px;
}
.box-hd {height: 45px;
}
.box-hd h3 {float: left;font-size: 20px;color: #494949;
}
.box-hd a {float: right;font-size: 12px;color: #a5a5a5;margin-top: 10px;margin-right: 30px;
}
/* 把li 的父亲ul 修改的足够宽一行能装开5个盒子就不会换行了 */
.box-bd ul {width: 1225px;
}
.box-bd ul li {position: relative;top: 0;float: left;width: 228px;height: 270px;background-color: #fff;margin-right: 15px;margin-bottom: 15px;transition: all .3s;}
.box-bd ul li a {display: block;
}
.box-bd ul li:hover {top: -8px;box-shadow: 0 15px 30px rgb(0 0 0 / 10%);
}
.box-bd ul li img {width: 100%;
}
.box-bd ul li h4 {margin: 20px 20px 20px 25px;font-size: 14px;color: #050505;font-weight: 400;
}
.box-bd .info {margin: 0 20px 0 25px;font-size: 12px;color: #999;
}
.box-bd .info span {color: #ff7c2d;
}
拓展-术语解释
拓展- 基本数据类型和引用数据类型
拓展- 变量声明
二、Web APIs
1. Web API 基本认知
1.1 作用和分类
Web API是浏览器提供的一套操作浏览器功能和页面元素的API(BOM和DOM)。
1.2 什么是DOM
1.3 DOM树
文档:一个页面就是一个文档,DOM中使用document表示
元素:页面中的所有标签都是元素,DOM中使用element表示
节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示
DOM 把以上内容都看做是对象
1.4 DOM对象(重要)
2.获取DOM对象
2.1 根据CSS选择器来获取DOM元素 (重点)
1. 选择匹配的第一个元素
语法:
document.querySelector('css选择器')
<body><div class="box">123</div><div class="box">abc</div><ul class="nav"><li>测试1</li><li>测试2</li><li>测试3</li></ul><script>// 获取匹配的第一个元素// const box = document.querySelector('div') // 123const box = document.querySelector('.box') //123console.log(box)// 获取 ul 第一个小 li// const li = document.querySelector('ul li')const li = document.querySelector('ul li:first-child')console.log(li)</script>
</body>
语法:
document.querySelectorAll('css选择器')
<body><ul class="nav"><li>测试1</li><li>测试2</li><li>测试3</li></ul><script>const lis = document.querySelectorAll('.nav li')console.log(lis)</script>
</body>
const lis = document.querySelectorAll('.nav li')for (let i = 0; i < lis.length; i++) {console.log(lis[i]) // 每一个小li对象}
<body><p id="nav">导航栏</p><script>const p = document.querySelectorAll('#nav')p[0].style.color = 'red'</script>
</body>
2.2 其他获取DOM元素方法(了解)
获取特殊元素
1. 获取body元素:doucumnet.body // 返回body元素对象
2. 获取html元素:document.documentElement // 返回html元素对象
3. 操作元素内容
<body><div class="box">我是文字的内容</div><script>// 1. 获取元素const box = document.querySelector('.box')// 2. 修改文字内容 对象.innerText 属性box.innerText = '我是一个盒子' // 修改文字内容// box.innerText = '<strong>我是一个盒子</strong>' // 不解析标签</script>
</body>
<body><div class="box">我是文字的内容</div><script>// 获取元素const box = document.querySelector('.box')// innerHTML 解析标签// box.innerHTML = '我要更换'box.innerHTML = '<strong>我要更换</strong>'</script>
</body>
<!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>// 1.声明数组const personArr = ['周杰伦', '刘德华', '周星驰', 'Pink老师', '张学友']// 2. 先做一等奖// 2.1 随机数 数组的下标const random = Math.floor(Math.random() * personArr.length)// console.log(personArr[random])// 2.2 获取one 元素 const one = document.querySelector('#one')// 2.3 把名字给 oneone.innerHTML = personArr[random]// 2.4 删除数组这个名字personArr.splice(random, 1)// console.log(personArr)// 3. 二等奖// 2.1 随机数 数组的下标const random2 = Math.floor(Math.random() * personArr.length)// console.log(personArr[random])// 2.2 获取one 元素 const two = document.querySelector('#two')// 2.3 把名字给 onetwo.innerHTML = personArr[random2]// 2.4 删除数组这个名字personArr.splice(random2, 1)// 4. 三等奖// 2.1 随机数 数组的下标const random3 = Math.floor(Math.random() * personArr.length)// console.log(personArr[random])// 2.2 获取one 元素 const three = document.querySelector('#three')// 2.3 把名字给 onethree.innerHTML = personArr[random3]// 2.4 删除数组这个名字personArr.splice(random3, 1)</script>
</body></html>
4.操作元素属性
4.1 操作元素常用属性
<body><img src="./images/1.webp" alt=""><script>// 1. 获取图片元素const img = document.querySelector('img')// 2. 修改图片对象的属性 对象.属性 = 值img.src = './images/2.webp'img.title = 'pink老师的艺术照'</script>
</body>
4.2 操作元素样式属性
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.box {width: 200px;height: 200px;color: #333;}.active {color: red;background-color: pink;}</style>
</head><body><div class="box active">文字</div><script>// 通过classList添加// 1. 获取元素const box = document.querySelector('.box')// 2. 修改样式// 2.1 追加类 add() 类名不加点,并且是字符串// box.classList.add('active')// 2.2 删除类 remove() 类名不加点,并且是字符串// box.classList.remove('box')// 2.3 切换类 toggle() 有还是没有啊, 有就删掉,没有就加上box.classList.toggle('active')</script>
</body></html>
案例:轮播图随机版
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>轮播图点击切换</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 class="slider-indicator"><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 sliderData = [{ url: './images/slider01.jpg', title: '对人类来说会不会太超前了?', color: 'rgb(100, 67, 68)' },{ url: './images/slider02.jpg', title: '开启剑与雪的黑暗传说!', color: 'rgb(43, 35, 26)' },{ url: './images/slider03.jpg', title: '真正的jo厨出现了!', color: 'rgb(36, 31, 33)' },{ url: './images/slider04.jpg', title: '李玉刚:让世界通过B站看到东方大国文化', color: 'rgb(139, 98, 66)' },{ url: './images/slider05.jpg', title: '快来分享你的寒假日常吧~', color: 'rgb(67, 90, 92)' },{ url: './images/slider06.jpg', title: '哔哩哔哩小年YEAH', color: 'rgb(166, 131, 143)' },{ url: './images/slider07.jpg', title: '一站式解决你的电脑配置问题!!!', color: 'rgb(53, 29, 25)' },{ url: './images/slider08.jpg', title: '谁不想和小猫咪贴贴呢!', color: 'rgb(99, 72, 114)' },]// 1. 需要一个随机数 const random = parseInt(Math.random() * sliderData.length)// console.log(sliderData[random])// 2. 把对应的数据渲染到标签里面// 2.1 获取图片const img = document.querySelector('.slider-wrapper img')// 2.2. 修改图片路径 = 对象.urlimg.src = sliderData[random].url// 3. 把p里面的文字内容更换// 3.1 获取pconst p = document.querySelector('.slider-footer p')// 3.2修改pp.innerHTML = sliderData[random].title// 4. 修改背景颜色const footer = document.querySelector('.slider-footer')footer.style.backgroundColor = sliderData[random].color// 5. 小圆点const li = document.querySelector(`.slider-indicator li:nth-child(${random + 1})`)// 让当前这个小li 添加 active这个类li.classList.add('active')</script>
</body></html>
4.3 操作表单元素属性
表单很多情况也需要修改属性,比如点击眼睛,可以看到密码,本质是把表单类型转换为文本框。
<body><button>点击</button><script>// 1.获取const button = document.querySelector('button')// console.log(button.disabled) // 默认false 不禁用button.disabled = true // 禁用按钮</script>
</body>
4.4 自定义属性
5.定时器-间歇函数
网页中经常会需要一种功能:每隔一段时间需要自动执行一段代码,不需要我们手动去触发。
例如:网页中的倒计时。要实现这种需求,需要定时器函数。
定时器函数可以开启和关闭定时器,可以根据时间自动重复执行某些代码。
1. 开启定时器
setInterval(函数, 间隔时间)
3. 间隔时间单位是毫秒(1s = 1000ms)
<script>// setInterval(函数, 间隔时间)// 1.直接写匿名函数// setInterval(function () {// console.log('一秒执行一次')// }, 1000)// 2.调用函数,只写函数名,不要加小括号function fn() {console.log('一秒执行一次')}let n = setInterval(fn, 1000)// setInterval('fn()', 1000)</script>
let 变量名 = setInterval(函数, 间隔时间)
clearInterval(变量名)
<body><textarea name="" id="" cols="30" rows="10">用户注册协议欢迎注册成为京东用户!在您注册过程中,您需要完成我们的注册流程并通过点击同意的形式在线签署以下协议,请您务必仔细阅读、充分理解协议中的条款内容后再点击同意(尤其是以粗体或下划线标识的条款,因为这些条款可能会明确您应履行的义务或对您的权利有所限制)。【请您注意】如果您不同意以下协议全部或任何条款约定,请您停止注册。您停止注册后将仅可以浏览我们的商品信息但无法享受我们的产品或服务。如您按照注册流程提示填写信息,阅读并点击同意上述协议且完成全部注册流程后,即表示您已充分阅读、理解并接受协议的全部内容,并表明您同意我们可以依据协议内容来处理您的个人信息,并同意我们将您的订单信息共享给为完成此订单所必须的第三方合作方(详情查看</textarea><br><button class="btn" disabled>我已经阅读用户协议(5)</button><script>// 1. 获取元素const btn = document.querySelector('.btn')// console.log(btn.innerHTML) butto按钮特殊用innerHTML// 2. 倒计时let i = 5// 2.1 开启定时器let n = setInterval(function () {i--btn.innerHTML = `我已经阅读用户协议(${i})`if (i === 0) {clearInterval(n) // 关闭定时器// 定时器停了,我就可以开按钮btn.disabled = falsebtn.innerHTML = '同意'}}, 1000)</script>
</body>
综合案例:轮播图定时器版
<!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 class="slider-indicator"><li class="active"></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><div class="toggle"><button class="prev"><</button><button class="next">></button></div></div></div><script>// 1. 初始数据const sliderData = [{ url: './images/slider01.jpg', title: '对人类来说会不会太超前了?', color: 'rgb(100, 67, 68)' },{ url: './images/slider02.jpg', title: '开启剑与雪的黑暗传说!', color: 'rgb(43, 35, 26)' },{ url: './images/slider03.jpg', title: '真正的jo厨出现了!', color: 'rgb(36, 31, 33)' },{ url: './images/slider04.jpg', title: '李玉刚:让世界通过B站看到东方大国文化', color: 'rgb(139, 98, 66)' },{ url: './images/slider05.jpg', title: '快来分享你的寒假日常吧~', color: 'rgb(67, 90, 92)' },{ url: './images/slider06.jpg', title: '哔哩哔哩小年YEAH', color: 'rgb(166, 131, 143)' },{ url: './images/slider07.jpg', title: '一站式解决你的电脑配置问题!!!', color: 'rgb(53, 29, 25)' },{ url: './images/slider08.jpg', title: '谁不想和小猫咪贴贴呢!', color: 'rgb(99, 72, 114)' },]// 1. 获取元素 const img = document.querySelector('.slider-wrapper img')const p = document.querySelector('.slider-footer p')let i = 0 // 信号量 控制图片的张数// 2. 开启定时器setInterval(function () {i++// 无缝衔接位置 一共八张图片,到了最后一张就是 8, 数组的长度就是 8if (i >= sliderData.length) {i = 0}// 更换图片路径 img.src = sliderData[i].url// 把字写到 p里面p.innerHTML = sliderData[i].title// 小圆点// 先删除以前的activedocument.querySelector('.slider-indicator .active').classList.remove('active')// 只让当前li添加activedocument.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')}, 1000)</script>
</body></html>
6.事件监听(绑定)
6.1 事件监听
什么是事件?
元素对象.addEventListener('事件类型', 要执行的函数)
<!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;}h2 {text-align: center;}.box {width: 600px;margin: 50px auto;display: flex;font-size: 25px;line-height: 40px;}.qs {width: 450px;height: 40px;color: red;}.btns {text-align: center;}.btns button {width: 120px;height: 35px;margin: 0 50px;}</style>
</head><body><h2>随机点名</h2><div class="box"><span>名字是:</span><div class="qs">这里显示姓名</div></div><div class="btns"><button class="start">开始</button><button class="end">结束</button></div><script>// 数据数组const arr = ['马超', '黄忠', '赵云', '关羽', '张飞']// 定时器的全局变量let timerId = 0// 随机号要全局变量let random = 0// 业务1.开始按钮模块const qs = document.querySelector('.qs')// 1.1 获取开始按钮对象const start = document.querySelector('.start')// 1.2 添加点击事件start.addEventListener('click', function () {timerId = setInterval(function () {// 随机数random = parseInt(Math.random() * arr.length)// console.log(arr[random])qs.innerHTML = arr[random]}, 35)// 如果数组里面只有一个值了,还需要抽取吗? 不需要 让两个按钮禁用就可以if (arr.length === 1) {// start.disabled = true// end.disabled = truestart.disabled = end.disabled = true}})// 2. 关闭按钮模块const end = document.querySelector('.end')end.addEventListener('click', function () {clearInterval(timerId)// 结束了,可以删除掉当前抽取的那个数组元素arr.splice(random, 1)console.log(arr)})</script>
</body></html>
6.2 事件监听版本
7.事件类型
案例:轮播图完整版
<!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 class="slider-indicator"><li class="active"></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><div class="toggle"><button class="prev"><</button><button class="next">></button></div></div></div><script>// 1. 初始数据const data = [{ url: './images/slider01.jpg', title: '对人类来说会不会太超前了?', color: 'rgb(100, 67, 68)' },{ url: './images/slider02.jpg', title: '开启剑与雪的黑暗传说!', color: 'rgb(43, 35, 26)' },{ url: './images/slider03.jpg', title: '真正的jo厨出现了!', color: 'rgb(36, 31, 33)' },{ url: './images/slider04.jpg', title: '李玉刚:让世界通过B站看到东方大国文化', color: 'rgb(139, 98, 66)' },{ url: './images/slider05.jpg', title: '快来分享你的寒假日常吧~', color: 'rgb(67, 90, 92)' },{ url: './images/slider06.jpg', title: '哔哩哔哩小年YEAH', color: 'rgb(166, 131, 143)' },{ url: './images/slider07.jpg', title: '一站式解决你的电脑配置问题!!!', color: 'rgb(53, 29, 25)' },{ url: './images/slider08.jpg', title: '谁不想和小猫咪贴贴呢!', color: 'rgb(99, 72, 114)' },]// 获取元素const img = document.querySelector('.slider-wrapper img')const p = document.querySelector('.slider-footer p')const footer = document.querySelector('.slider-footer')// 1. 右按钮业务// 1.1 获取右侧按钮 const next = document.querySelector('.next')let i = 0 // 信号量 控制播放图片张数// 1.2 注册点击事件next.addEventListener('click', function () {i++i = i >= data.length ? 0 : i// 调用函数toggle()})// 2. 左侧按钮业务// 2.1 获取左侧按钮 const prev = document.querySelector('.prev')// 2.2 注册点击事件prev.addEventListener('click', function () {i--i = i < 0 ? data.length - 1 : i// 调用函数toggle()})// 声明一个渲染的函数作为复用function toggle() {// 1.4 渲染对应的数据img.src = data[i].urlp.innerHTML = data[i].titlefooter.style.backgroundColor = data[i].color// 1.5 更换小圆点 先移除原来的类名, 当前li再添加 这个 类名document.querySelector('.slider-indicator .active').classList.remove('active')document.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')}// 3. 自动播放模块let timerId = setInterval(function () {// 利用js自动调用点击事件 click() 一定加小括号调用函数next.click()}, 1000)// 4. 鼠标经过大盒子,停止定时器const slider = document.querySelector('.slider')// 注册事件slider.addEventListener('mouseenter', function () {// 停止定时器clearInterval(timerId)})// 5. 鼠标离开大盒子,开启定时器// 注册事件slider.addEventListener('mouseleave', function () {// 停止定时器if (timerId) clearInterval(timerId)// 开启定时器timerId = setInterval(function () {// 利用js自动调用点击事件 click() 一定加小括号调用函数next.click()}, 1000)})</script>
</body></html>
8.事件对象
8.1 获取事件对象
8.2 事件对象常用属性
<!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">zhuie</p><p class="text">大家都辛苦啦,感谢各位大大的努力,能圆满完成真是太好了[笑哭][支持]</p><p class="time">2023-05-17 20:33:21</p></div></div></div><script>const tx = document.querySelector('#tx')const total = document.querySelector('.total')const item = document.querySelector('.item')const text = document.querySelector('.text')// 1. 当我们文本域获得了焦点,就让 total 显示出来tx.addEventListener('focus', function () {total.style.opacity = 1})// 2. 当我们文本域失去了焦点,就让 total 隐藏出来tx.addEventListener('blur', function () {total.style.opacity = 0})// 3. 检测用户输入tx.addEventListener('input', function () {// console.log(tx.value.length) 得到输入的长度total.innerHTML = `${tx.value.length}/200字`})// 4. 按下回车发布评论tx.addEventListener('keyup', function (e) {// 只有按下的是回车键,才会触发if (e.key === 'Enter') {// 如果用户输入的不为空就显示和打印if (tx.value.trim()) {item.style.display = 'block'// console.log(tx.value) // 用户输入的内容text.innerHTML = tx.value}// 等我们按下回车,结束,清空文本域tx.value = ''// 按下回车之后,就要把 字符统计 复原total.innerHTML = '0/200字'}})</script>
</body></html>
9.环境对象
10.回调函数
综合案例:Tab栏切换
<!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 模块制作 要给 5个链接绑定鼠标经过事件// 1.1 获取 a 元素 const as = document.querySelectorAll('.tab-nav a')for (let i = 0; i < as.length; i++) {// 要给 5个链接绑定鼠标经过事件as[i].addEventListener('mouseenter', function () { // 鼠标经过// 排他思想 // 干掉别人 移除类activedocument.querySelector('.tab-nav .active').classList.remove('active')// 我登基 我添加类 active this 当前的那个 a this.classList.add('active')// 下面5个大盒子 一一对应 .item // 干掉别人document.querySelector('.tab-content .active').classList.remove('active')// 对应序号的那个 item 显示 添加 active 类document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')})}</script>
</body></html>
拓展:css伪类选择器checked(选择被勾选的复选框)
重点案例:全选文本框
<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title></title><style>* {margin: 0;padding: 0;}table {border-collapse: collapse;border-spacing: 0;border: 1px solid #c0c0c0;width: 500px;margin: 100px auto;text-align: center;}th {background-color: #09c;font: bold 16px "微软雅黑";color: #fff;height: 24px;}td {border: 1px solid #d0d0d0;color: #404060;padding: 10px;}.allCheck {width: 80px;}</style>
</head><body><table><tr><th class="allCheck"><input type="checkbox" name="" id="checkAll"> <span class="all">全选</span></th><th>商品</th><th>商家</th><th>价格</th></tr><tr><td><input type="checkbox" name="check" class="ck"></td><td>小米手机</td><td>小米</td><td>¥1999</td></tr><tr><td><input type="checkbox" name="check" class="ck"></td><td>小米净水器</td><td>小米</td><td>¥4999</td></tr><tr><td><input type="checkbox" name="check" class="ck"></td><td>小米电视</td><td>小米</td><td>¥5999</td></tr></table><script>// 1. 获取大复选框const checkAll = document.querySelector('#checkAll')// 2. 获取所有的小复选框const cks = document.querySelectorAll('.ck')// 3. 点击大复选框 注册事件checkAll.addEventListener('click', function () {// 得到当前大复选框的选中状态// console.log(checkAll.checked) // 得到 是 true 或者是 false// 4. 遍历所有的小复选框 让小复选框的checked = 大复选框的 checkedfor (let i = 0; i < cks.length; i++) {cks[i].checked = this.checked}})// 5. 小复选框控制大复选框for (let i = 0; i < cks.length; i++) {// 5.1 给所有的小复选框添加点击事件cks[i].addEventListener('click', function () {// 判断选中的小复选框个数 是不是等于 总的小复选框个数// console.log(document.querySelectorAll('.ck:checked').length)// console.log(document.querySelectorAll('.ck:checked').length === cks.length)checkAll.checked = document.querySelectorAll('.ck:checked').length === cks.length})}</script>
</body></html>
11.事件流
11.1 事件流和两个阶段说明
11.2 事件捕获
11.3 事件冒泡
11.4 阻止冒泡
<body><div class="father"><div class="son"></div></div><script>const fa = document.querySelector('.father')const son = document.querySelector('.son')document.addEventListener('click', function () {alert('我是爷爷')})fa.addEventListener('click', function () {alert('我是爸爸')})son.addEventListener('click', function (e) {alert('我是儿子')// 阻止流动传播 事件对象.stopPropagation()e.stopPropagation()})</script>
</body>
<body><form action="http://www.itcast.cn"><input type="submit" value="免费注册"></form><script>const form = document.querySelector('form')form.addEventListener('submit', function (e) {// 阻止默认行为 提交e.preventDefault()})</script>
</body>
11.5 解绑事件
<body><button>点击</button><script>const btn = document.querySelector('button')btn.onclick = function () {alert('点击了')// L0 事件移除解绑btn.onclick = null}</script>
</body>
<body><button>点击</button><script>const btn = document.querySelector('button')function fn() {alert('点击了')}btn.addEventListener('click', fn)// L2 事件移除解绑btn.removeEventListener('click', fn)</script>
</body>
拓展:鼠标经过事件的区别、两种注册事件的区别
12.事件委托
案例:tab栏切换改造
<!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:;" data-id="0">精选</a></li><li><a href="javascript:;" data-id="1">美食</a></li><li><a href="javascript:;" data-id="2">百货</a></li><li><a href="javascript:;" data-id="3">个护</a></li><li><a href="javascript:;" data-id="4">预告</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>// 采取事件委托的形式 tab栏切换// 1. 获取 ul 父元素 因为 ul只有一个const ul = document.querySelector('.tab-nav ul')// 获取 5个 item const items = document.querySelectorAll('.tab-content .item')// 2. 添加事件ul.addEventListener('click', function (e) {// console.log(e.target) // e.target是我们点击的对象// 我们只有点击了 a 才会 进行 添加类和删除类操作 // console.log(e.target.tagName) // e.target.tagName 点击那个对象的 标签名if (e.target.tagName === 'A') {// console.log('我选的是a')// 排他思想 ,先移除原来的active document.querySelector('.tab-nav .active').classList.remove('active')//当前元素添加 active 是 e.target// this 指向ul 不能用this e.target.classList.add('active')// 下面大盒子模块// console.log(e.target.dataset.id)// 获取的是字符串,需转换为数字const i = +e.target.dataset.id// 排他思想 ,先移除原来的active document.querySelector('.tab-content .active').classList.remove('active')// 对应的大盒子 添加 active // document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')items[i].classList.add('active')}})</script>
</body></html>
13.其他事件
13.1 页面加载事件
13.2 页面滚动事件
<script>const div = document.querySelector('div')// 页面滚动事件window.addEventListener('scroll', function () {// 获取html元素写法 // document.documentElement const n = document.documentElement.scrollTopif (n >= 100) {div.style.display = 'block'} else {div.style.display = 'none'}})</script>
注意:document.documentElement HTML文档返回对象为HTML元素
13.2 页面滚动事件-滚动到指定的坐标
<script>// 点击返回页面顶部const backTop = document.querySelector('#backTop')backTop.addEventListener('click', function () {// 可读写// document.documentElement.scrollTop = 0window.scrollTo(0, 0)})</script>
13.3 页面尺寸事件
会在窗口尺寸改变的时候触发事件:resize
案例:Rem基准值
13.4 元素尺寸与位置
案例:仿京东固定导航栏案例
<body><div class="header">我是顶部导航栏</div><div class="content"><div class="sk">秒杀模块</div></div><div class="backtop"><img src="./images/close2.png" alt=""><a href="javascript:;"></a></div><script>const sk = document.querySelector('.sk')const header = document.querySelector('.header')// 页面滚动事件window.addEventListener('scroll', function () {// 当页面滚动到 秒杀模块的时候,就改变 头部的 top值// 页面被卷去的头部 >= 秒杀模块的位置 offsetTopconst n = document.documentElement.scrollTopheader.style.top = n >= sk.offsetTop ? 0 : '-80px'})</script>
</body>
案例:实现bilibili 点击小滑块移动效果
<script>// 1. 事件委托的方法 获取父元素 tabs-listconst list = document.querySelector('.tabs-list')const line = document.querySelector('.line')// 2. 注册点击事件list.addEventListener('click', function (e) {// 只有点击了A 才有触发效果if (e.target.tagName === 'A') {// 得到当前点击元素的位置// console.log(e.target.offsetLeft)// 把我们点击的a链接盒子的位置 然后移动line.style.transform = `translateX(${e.target.offsetLeft}px)`}})</script>
总结
综合案例:电梯导航
<script>// 第一大模块,页面滑动可以显示和隐藏(function () {// 获取元素const entry = document.querySelector('.xtx_entry')const elevator = document.querySelector('.xtx-elevator')// 1. 当页面滚动大于 300像素,就显示 电梯导航// 2. 给页面添加滚动事件window.addEventListener('scroll', function () {// 被卷去的头部大于 300 const n = document.documentElement.scrollTopelevator.style.opacity = n >= entry.offsetTop ? 1 : 0})// 点击返回页面顶部const backTop = document.querySelector('#backTop')backTop.addEventListener('click', function () {// 可读写// document.documentElement.scrollTop = 0window.scrollTo(0, 0)})})();// 第二第三都放到另外一个执行函数里面(function () {// 2. 点击页面可以滑动 const list = document.querySelector('.xtx-elevator-list')list.addEventListener('click', function (e) {// console.log(11)if (e.target.tagName === 'A' && e.target.dataset.name) {// 排他思想 // 先移除原来的类active // 先获取这个active的对象const old = document.querySelector('.xtx-elevator-list .active')// console.log(old)// 判断 如果原来有active类的对象,就移除类,如果开始就没有对象,就不删除,所以不报错if (old) old.classList.remove('active')// 当前元素添加 active e.target.classList.add('active')// 获得自定义属性 new topic // console.log(e.target.dataset.name)// 根据小盒子的自定义属性值 去选择 对应的大盒子// console.log(document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop)// 获得对应大盒子的 offsetTopconst top = document.querySelector(`.xtx_goods_${e.target.dataset.name}`).offsetTop// 让页面滚动到对应的位置document.documentElement.scrollTop = top}})// 3. 页面滚动,可以根据大盒子选 小盒子 添加 active 类window.addEventListener('scroll', function () {// 3.1 先移除类 // 先获取这个active的对象const old = document.querySelector('.xtx-elevator-list .active')// console.log(old)// 判断 如果原来有active类的对象,就移除类,如果开始就没有对象,就不删除,所以不报错if (old) old.classList.remove('active')// 3.2 判断页面当前滑动的位置,选择小盒子// 获取4个大盒子const news = document.querySelector('.xtx_goods_new')const popular = document.querySelector('.xtx_goods_popular')const brand = document.querySelector('.xtx_goods_brand')const topic = document.querySelector('.xtx_goods_topic')const n = document.documentElement.scrollTopif (n >= news.offsetTop && n < popular.offsetTop) {// 选择第一个小盒子document.querySelector('[data-name=new]').classList.add('active')} else if (n >= popular.offsetTop && n < brand.offsetTop) {document.querySelector('[data-name=popular]').classList.add('active')} else if (n >= brand.offsetTop && n < topic.offsetTop) {document.querySelector('[data-name=brand]').classList.add('active')} else if (n >= topic.offsetTop) {document.querySelector('[data-name=topic]').classList.add('active')}})})();</script>
14. 日期对象
JavaScript 学习笔记 超详细(b站pink老师)相关推荐
- CSS学习笔记(跟随b站pink老师)
.CSS 一.CSS简介 1.1.CSS语法规范 使用HTML时,需要遵从一定的规范,CSS也是如此.熟练使用CSS对网页进行修饰,首先需要了解CSS样式规则. CSS规则由两个主要的部分构成:选择器 ...
- STM32学习笔记(超详细)
查看全文 http://www.taodudu.cc/news/show-6770803.html 相关文章: STM32单片机学习笔记(超详细整理143个问题,学习必看) vsb asc_vsb电力 ...
- 吴恩达推荐深度学习笔记+超详细思维导图!不做学术打工人!
关于人工智能的分支-深度学习版块的资源有很多,但是都会较为分散.小编今天对这些资源进行了整理归纳,汇编了一套学习资源(包含书籍+电子书+百篇论文+思维导图+吴恩达深度学习笔记大全+计算机视觉学术汇总) ...
- 【数据可视化】Matplotlib 入门到精通学习笔记(超详细)
数据可视化是什么 如果将文本数据与图表数据相比较,人类的思维模式更适合于理解后者,原因在于图表数据更加直观且形象化,它对于人类视觉的冲击更强,这种使用图表来表示数据的方法被叫做数据可视化. 当使用图表 ...
- JSF学习笔记超详细,从入门到精通,持续更新中~
JSF笔记 1.JSF概述 JavaServer Faces (JSF) 是一种用于构建Java Web 应用程序的标准框架(是Java Community Process 规定的JSR-127标准) ...
- mysql 8.0.26学习笔记超详细入门到精通
目录 1.基本的SELECT语句 1.1 查询表中特定字段 1.2 字段取别名 1.3 数据去重 1.4 数据空值替换 1.5 显示表的结构 1.6 条件查询where 2.算术运算符 3.比较运算符 ...
- STM32学习笔记---超详细整理144个问题
1.AHB系统总线分为APB1(36MHz)和APB2(72MHz),其中2>1,意思是APB2接高速设备: 2.Stm32f10x.h相当于reg52.h(里面有基本的位操作定义),另一个为s ...
- Redis学习笔记(超详细,看完必会)
开头: 1.Redis基本概念 Redis是一个<K,V>键值对的数据库,大量操作都是在内存中完成的,读写的效率很高,因此广泛用于缓存 Redis是单线程的 Redis实际上是采用了线程封 ...
- JavaScript学习笔记(四)(DOM)
JavaScript学习笔记(四) DOM 一.DOM概述 二.元素对象 2.1 获取方式 (1).通过ID获取一个元素对象,如果没有返回null (2).通过`标签名`获取一组元素对象,,如果没有返 ...
最新文章
- [JOISC2014]ストラップ
- 在线IDE之关键字另色显示
- 强力推荐!飞桨产业级PaddleNLP最新全景图发布
- Struts 体系结构与工作原理(图)
- XI 安装MS SQLSERVER JDBC 驱动
- python xlwt模块使用_Python xlwt模块使用代码实例
- MySQL在DOS下的基本命令操作
- 【qduoj - 纳新题】凑数题(恰好装满类0-1背包 或 母函数)
- 请给出计算231-1的python表达式_【填空题】计算2 32 -1的Python表达式可以书写为____...
- 哈希表和红黑树的对比
- 思想篇(1)--企业需要什么样的人才?
- L3-029 还原文件 (30 分)-PAT 团体程序设计天梯赛 GPLT
- ADO.NET数据访问模式
- 挑战程序设计竞赛:Conscription
- python爬虫微信_python 微信爬虫
- Redis中五中数据类型的实例
- 压电式雨量传感器数字感知降雨量
- java图片加水印上传工具类_基于Spring Boot实现图片上传/加水印一把梭操作
- foxmail邮箱怎么导入邮件_Foxmail怎样导入和导出邮箱账户和邮件
- Docker 容器化技术(介绍)
热门文章
- 古琴调音频率及音位图(正调F调)
- 【杂烩】Tesla M40 24G 在Win11上的双显卡显示实现、改风冷
- linux哪个版本支持tipc,TIPC协议和实现解析
- PowerMill 2018三五轴编程+后处理制作视频教程
- OpenCV-图像颗粒感
- java备忘--20190828
- keep-alive 的作用及使用场景
- Laravel 5 - Trait method can has not been applied, because there are collisions with other trai
- RIoTBoard开发板系列笔记(十二)—— gstreamer + vpu实现视频硬件解码播放
- 嵌入式监控【v4l2采集-vpu编码-live555推流】