JavaScript 基础 - 第1天
了解变量、数据类型、运算符等基础概念,能够实现数据类型的转换,结合四则运算体会如何编程。
体会现实世界中的事物与计算机的关系
理解什么是数据并知道数据的分类
理解变量存储数据的“容器”
掌握常见运算符的使用,了解优先级关系
知道 JavaScript 数据类型隐式转换的特征
介绍
掌握 JavaScript 的引入方式,初步认识 JavaScript 的作用
引入方式 JavaScript 程序不能独立运行,它需要被嵌入 HTML 中,然后浏览器才能执行 JavaScript 代码。通过 script
标签将 JavaScript 代码引入到 HTML 中,有两种方式:
内部方式 通过 script
标签包裹 JavaScript 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 引入方式</title > </head > <body > <script > alert ('嗨,欢迎来传智播学习前端技术!' ) </script > </body > </html >
外部形式 一般将 JavaScript 代码写在独立的以 .js 结尾的文件中,然后通过 script
标签的 src
属性引入
1 2 document .write ('嗨,欢迎来传智播学习前端技术!' )
1 2 3 4 5 6 7 8 9 10 11 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 引入方式</title > </head > <body > <script src ="demo.js" > </script > </body > </html >
如果 script 标签使用 src 属性引入了某 .js 文件,那么 标签的代码会被忽略!!!如下代码所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 引入方式</title > </head > <body > <script src ="demo.js" > alert (666 ); </script > </body > </html >
注释和结束符 通过注释可以屏蔽代码被执行或者添加备注信息,JavaScript 支持两种形式注释语法:
单行注释 使用 //
注释单行代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 注释</title > </head > <body > <script > document .write ('嗨,欢迎来传智播学习前端技术!' ); </script > </body > </html >
多行注释 使用 /* */
注释多行代码
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" > <title > JavaScript 基础 - 注释</title > </head > <body > <script > document .write ('嗨,欢迎来传智播学习前端技术!' ) </script > </body > </html >
注:编辑器中单行注释的快捷键为 ctrl + /
结束符 在 JavaScript 中 ;
代表一段代码的结束,多数情况下可以省略 ;
使用回车(enter)替代。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 结束符</title > </head > <body > <script > alert(1); alert(2); alert(1) alert(2) </script > </body > </html >
实际开发中有许多人主张书写 JavaScript 代码时省略结束符 ;
输入和输出 输出和输入也可理解为人和计算机的交互,用户通过键盘、鼠标等向计算机输入信息,计算机处理后再展示结果给用户,这便是一次输入和输出的过程。
举例说明:如按键盘上的方向键,向上/下键可以滚动页面,按向上/下键这个动作叫作输入,页面发生了滚动了这便叫输出。
输出 JavaScript 可以接收用户的输入,然后再将输入的结果输出:
alert()
、document.wirte()
以数字为例,向 alert()
或 document.write()
输入任意数字,他都会以弹窗形式展示(输出)给用户。
控制台输出为console.log()
输入 向 prompt()
输入任意内容会以弹窗形式出现在浏览器中,一般提示用户输入一些内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 输入输出</title > </head > <body > <script > document .write ('要输出的内容' ) alert ('要输出的内容' ); prompt ('请输入您的姓名:' ) </script > </body > </html >
变量
理解变量是计算机存储数据的“容器”,掌握变量的声明方式
变量是计算机中用来存储数据的“容器”,它可以让计算机变得有记忆,通俗的理解变量就是使用【某个符号】来代表【某个具体的数值】(数据)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <script > x = 5 y = 6 num = prompt ('请输入一数字!' ) alert (num) document .write (num) </script >
声明 声明(定义)变量有两部分构成:声明关键字、变量名(标识)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 声明和赋值</title > </head > <body > <script > let age </script > </body > </html >
关键字是 JavaScript 中内置的一些英文词汇(单词或缩写),它们代表某些特定的含义,如 let
的含义是声明变量的,看到 let
后就可想到这行代码的意思是在声明变量,如 let age;
let
和 var
都是 JavaScript 中的声明变量的关键字,推荐使用 let
声明变量!!!
赋值 声明(定义)变量相当于创造了一个空的“容器”,通过赋值向这个容器中添加数据。
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" > <title > JavaScript 基础 - 声明和赋值</title > </head > <body > <script > let age age = 18 document .write (age) let str = 'hello world!' alert (str); </script > </body > </html >
关键字 JavaScript 使用专门的关键字 let
和 var
来声明(定义)变量,在使用时需要注意一些细节:
以下是使用 let
时的注意事项:
允许声明和赋值同时进行
不允许重复声明
允许同时声明多个变量并赋值
JavaScript 中内置的一些关键字不能被当做变量名
以下是使用 var
时的注意事项:
可以先使用 再声明(不合理)
允许声明和赋值同时进行
允许重复声明
允许同时声明多个变量并赋值
比如变量提、全局变量、没有块级作用域等等
大部分情况使用 let
和 var
区别不大,但是 let
相较 var
更严谨,因此推荐使用 let
,后期会更进一步介绍二者间的区别。
变量名命名规则 关于变量的名称(标识符)有一系列的规则需要遵守:
只能是字母、数字、下划线、$,且不能能数字开头
字母区分大小写,如 Age 和 age 是不同的变量
JavaScript 内部已占用于单词(关键字或保留字)不允许使用
尽量保证变量具有一定的语义,见字知义
注:所谓关键字是指 JavaScript 内部使用的词语,如 let
和var
,保留字是指 JavaScript 内部目前没有使用的词语,但是将来可能会使用词语。
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" > <title > JavaScript 基础 - 变量名命名规则</title > </head > <body > <script > let age = 18 let age1 = 18 let _age = 18 let $age = 18 let Age = 24 let int = 123 </script > </body > </html >
常量 概念:使用 const 声明的变量称为“常量”。
使用场景:当某个变量永远不会改变的时候,就可以使用 const 来声明,而不是let。
命名规范:和变量一致
注意: 常量不允许重新赋值,声明的时候必须赋值(初始化)
数据类型
计算机世界中的万事成物都是数据。
计算机程序可以处理大量的数据,为了方便数据的管理,将数据分成了不同的类型:
注:通过typeof
关键字检测数据类型,它支持两种语法形式:
作为运算符:typeof x
(常用的写法)
函数形式:typeof(x)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 数据类型</title > </head > <body > <script > document .write (typeof 1 ) </script > </body > </html >
数值类型 即我们数学中学习到的数字,可以是整数、小数、正数、负数
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" > <title > JavaScript 基础 - 数据类型</title > </head > <body > <script > let score = 100 let price = 12.345 let temperature = -40 document .write (typeof score) document .write (typeof price) document .write (typeof temperature) </script > </body > </html >
JavaScript 中的数值类型与数学中的数字是一样的,分为正数、负数、小数等。
字符串类型 通过单引号( ''
) 、双引号( ""
)或反引号包裹的数据都叫字符串,单引号和双引号没有本质上的区别,推荐使用单引号。
注意事项:
无论单引号或是双引号必须成对使用
单引号/双引号可以互相嵌套,但是不以自已嵌套自已
必要时可以使用转义符 \
,输出单引号或双引号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 数据类型</title > </head > <body > <script > let user_name = '小明' let gender = "男" let str = '123' let str1 = '' documeent.write (typeof user_name) documeent.write (typeof gender) documeent.write (typeof str) </script > </body > </html >
布尔类型 表示肯定或否定时在计算机中对应的是布尔类型数据,它有两个固定的值 true
和 false
,表示肯定的数据用 true
,表示否定的数据用 false
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 数据类型</title > </head > <body > <script > let isCool = true isCool = false document .write (typeof isCool) </script > </body > </html >
undefined 未定义是比较特殊的类型,只有一个值 undefined,只声明变量,不赋值的情况下,变量的默认值为 undefined,一般很少【直接】为某个变量赋值为 undefined。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 数据类型</title > </head > <body > <script > let tmp; document .write (typeof tmp) </script > </body > </html >
注:JavaScript 中变量的值决定了变量的数据类型。
类型转换
理解弱类型语言的特征,掌握显式类型转换的方法
在 JavaScript 中数据被分成了不同的类型,如数值、字符串、布尔值、undefined,在实际编程的过程中,不同数据类型之间存在着转换的关系。
隐式转换 某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换称为隐式转换。
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 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 隐式转换</title > </head > <body > <script > let num = 13 let num2 = '2' console .log (num + num2) console .log (num - num2) let a = prompt ('请输入一个数字' ) let b = prompt ('请再输入一个数字' ) alert (a + b); </script > </body > </html >
注:数据类型的隐式转换是 JavaScript 的特征,后续学习中还会遇到,目前先需要理解什么是隐式转换。
补充介绍模板字符串的拼接的使用
显式转换 编写程序时过度依靠系统内部的隐式转换是不严禁的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。为了避免因隐式转换带来的问题,通常根逻辑需要对数据进行显示转换。
Number 通过 Number
显示转换成数值类型,当转换失败时结果为 NaN
(Not a Number)即不是一个数字。
注:NaN
也是number类型的数据,代表非数字
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" > <title > JavaScript 基础 - 隐式转换</title > </head > <body > <script > let t = '12' let f = 8 t = Number (t) console .log (t + f) let str = 'hello' console .log (Number (str)) </script > </body > </html >
JavaScript 基础 - 第2天
理解什么是流程控制,知道条件控制的种类并掌握其对应的语法规则,具备利用循环编写简易ATM取款机程序能力
运算符 算术运算符 数字是用来计算的,比如:乘法 * 、除法 / 、加法 + 、减法 - 等等,所以经常和算术运算符一起。
算术运算符:也叫数学运算符,主要包括加、减、乘、除、取余(求模)等
运算符
作用
+
求和
-
求差
*
求积
/
求商
%
取模(取余数),开发中经常用于作为某个数字是否被整除
注意:在计算失败时,显示的结果是 NaN (not a number)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 console .log (1 + 2 * 3 / 2 ) let num = 10 console .log (num + 10 ) console .log (num + num) console .log (4 % 2 ) console .log (6 % 3 ) console .log (5 % 3 ) console .log (3 % 5 ) console .log ('pink老师' - 2 )console .log ('pink老师' * 2 )console .log ('pink老师' + 2 )
赋值运算符 赋值运算符:对变量进行赋值的运算符
= 将等号右边的值赋予给左边, 要求左边必须是一个容器
运算符
作用
+=
加法赋值
-+
减法赋值
*=
乘法赋值
/=
除法赋值
%=
取余赋值
1 2 3 4 5 6 7 8 <script> let num = 1 num += 3 console .log (num)</script>
自增/自减运算符
符号
作用
说明
++
自增
变量自身的值加1,例如: x++
–
自减
变量自身的值减1,例如: x–
++在前和++在后在单独使用时二者并没有差别,而且一般开发中我们都是独立使用
++在后(后缀式)我们会使用更多
注意:
只有变量能够使用自增和自减运算符
++、– 可以在变量前面也可以在变量后面,比如: x++ 或者 ++x
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <script> let i = 1 console .log (i++ + ++i + i) </script>
前置自增:先自加再使用(记忆口诀:++在前 先加)
后置自增:先使用再自加(记忆口诀:++在后 后加)
比较运算符 使用场景:比较两个数据大小、是否相等,根据比较结果返回一个布尔值(true / false)
运算符
作用
>
左边是否大于右边
<
左边是否小于右边
>=
左边是否大于或等于右边
<=
左边是否小于或等于右边
===
左右两边是否类型
和值
都相等(重点)
==
左右两边值
是否相等
!=
左右值不相等
!==
左右两边是否不全等
注意:尽量不要比较小数,因为小数有精度问题!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <script> console .log (3 > 5 ) console .log (3 >= 3 ) console .log (2 == 2 ) console .log (2 == '2' ) console .log (2 === '2' ) console .log (NaN === NaN ) console .log (2 !== '2' ) console .log (2 != '2' ) console .log ('-------------------------' ) console .log ('a' < 'b' ) console .log ('aa' < 'ab' ) console .log ('aa' < 'aac' ) console .log ('-------------------------' ) </script>
逻辑运算符 使用场景:可以把多个布尔值放到一起运算,最终返回一个布尔值
符号
名称
日常读法
特点
口诀
&&
逻辑与
并且
符号两边有一个假的结果为假
一假则假
||
逻辑或
或者
符号两边有一个真的结果为真
一真则真
!
逻辑非
取反
true变false false变true
真变假,假变真
A
B
A && B
A || B
!A
false
false
false
false
true
false
true
false
true
true
true
false
false
true
false
true
true
true
true
false
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <script> console .log (true && true ) console .log (false && true ) console .log (3 < 5 && 3 > 2 ) console .log (3 < 5 && 3 < 2 ) console .log ('-----------------' ) console .log (true || true ) console .log (false || true ) console .log (false || false ) console .log ('-----------------' ) console .log (!true ) console .log (!false ) console .log ('-----------------' ) let num = 6 console .log (num > 5 && num < 10 ) console .log ('-----------------' ) </script>
运算符优先级
逻辑运算符优先级: !> && > ||
语句 表达式和语句
程序三大控制语句:顺序结构、分支结构、循环结构。
分支语句 分支语句可以根据条件判定真假,来选择性的执行想要的代码
分支语句包含:
if分支语句(重点)
三元运算符
switch语句
if 分支语句 语法:
小括号内的条件结果是布尔值,为 true 时,进入大括号里执行代码;为false,则不执行大括号里面代码
小括号内的结果若不是布尔类型时,会发生类型转换为布尔值,类似Boolean()
如果大括号只有一个语句,大括号可以省略,但是,俺们不提倡这么做~
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> let score = +prompt ('请输入成绩' ) if (score >= 700 ) { alert ('恭喜考入黑马程序员' ) } console .log ('-----------------' ) </script>
if双分支语句 如果有两个条件的时候,可以使用 if else 双分支语句
1 2 3 4 5 if (条件表达式){ } else { }
例如:
1 2 3 4 5 6 7 8 9 10 11 <script> let uname = prompt ('请输入用户名:' ) let pwd = prompt ('请输入密码:' ) if (uname === 'pink' && pwd === '123456' ) { alert ('恭喜登录成功' ) } else { alert ('用户名或者密码错误' ) } </script>
if 多分支语句 使用场景: 适合于有多个条件的时候
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <script> let score = +prompt ('请输入成绩:' ) if (score >= 90 ) { alert ('成绩优秀,宝贝,你是我的骄傲' ) } else if (score >= 70 ) { alert ('成绩良好,宝贝,你要加油哦~~' ) } else if (score >= 60 ) { alert ('成绩及格,宝贝,你很危险~' ) } else { alert ('成绩不及格,宝贝,我不想和你说话,我只想用鞭子和你说话~' ) } </script>
三元运算符(三元表达式) 使用场景 : 一些简单的双分支,可以使用 三元运算符(三元表达式),写起来比 if else双分支 更简单
符号 :? 与 : 配合使用
语法:
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 console .log (5 < 3 ? '真的' : '假的' )let num = prompt ('请您输入一个数字:' )num = num >= 10 ? num : 0 + num alert (num)
switch语句(了解) 使用场景: 适合于有多个条件的时候,也属于分支语句,大部分情况下和 if多分支语句 功能相同
注意:
switch case语句一般用于等值判断, if适合于区间判断
switchcase一般需要配合break关键字使用 没有break会造成case穿透
if 多分支语句开发要比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 <script> switch (2 ) { case 1 : console .log ('您选择的是1' ) break case 2 : console .log ('您选择的是2' ) break case 3 : console .log ('您选择的是3' ) break default : console .log ('没有符合条件的' ) } </script>
断点调试 作用: 学习时可以帮助更好的理解代码运行,工作时可以更快找到bug
浏览器打开调试界面
按F12打开开发者工具
点到源代码一栏 ( sources )
选择代码文件
断点: 在某句代码上加的标记就叫断点,当程序执行到这句有标记的代码时会暂停下来
循环语句 使用场景:重复执行 指定的一段代码,比如我们想要输出10次 ‘我学的很棒’
学习路径:
1.while循环
2.for 循环(重点)
while循环 while : 在…. 期间, 所以 while循环 就是在满足条件期间,重复执行某些代码。
语法:
例如:
1 2 3 4 5 6 7 8 let i = 1 while (i <= 3 ) { document .write ('月薪过万不是梦,毕业时候见英雄~<br>' ) i++ }
循环三要素:
1.初始值 (经常用变量)
2.终止条件
3.变量的变化量
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <script> let end = +prompt ('请输入次数:' ) let i = 1 while (i <= end) { document .write ('我要循环三次 <br>' ) i++ } </script>
中止循环 break
中止整个循环,一般用于结果已经得到, 后续的循环不需要的时候可以使用(提高效率)
continue
中止本次循环,一般用于排除或者跳过某一个选项的时候
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <script> let i = 1 while (i <= 5 ) { if (i === 3 ) { i++ continue } console .log (i) i++ } </script>
无限循环 1.while(true) 来构造“无限”循环,需要使用break退出循环。(常用)
2.for(;;) 也可以来构造“无限”循环,同样需要使用break退出循环。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 for (; ;) { let love = prompt ('你爱我吗?' ) if (love === '爱' ) { break } }
综合案例-ATM存取款机
分析:
①:提示输入框写到循环里面(无限循环)
②:用户输入4则退出循环 break
③:提前准备一个金额预先存储一个数额 money
④:根据输入不同的值,做不同的操作
(1) 取钱则是减法操作, 存钱则是加法操作,查看余额则是直接显示金额
(2) 可以使用 if else if 多分支 来执行不同的操作
完整代码:
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 <script> let money = 100 while (true ) { let re = +prompt (` 请您选择操作: 1.存钱 2.取钱 3.查看余额 4.退出 ` ) if (re === 4 ) { break } switch (re) { case 1 : let cun = +prompt ('请输入存款金额' ) money = money + cun break case 2 : let qu = +prompt ('请输入取款金额' ) money = money - qu break case 3 : alert (`您的银行卡余额是${money} ` ) break } } </script>
JavaScript 基础- 第3天笔记 if 多分支语句和 switch的区别:
共同点
都能实现多分支选择, 多选1
大部分情况下可以互换
区别:
switch…case语句通常处理case为比较确定值 的情况,而if…else…语句更加灵活,通常用于范围判断 (大于,等于某个范围)。
switch 语句进行判断后直接执行到程序的语句,效率更高,而if…else语句有几种判断条件,就得判断多少次
switch 一定要注意 必须是 === 全等,一定注意 数据类型,同时注意break否则会有穿透效果
结论:
当分支比较少时,if…else语句执行效率高。
当分支比较多时,switch语句执行效率高,而且结构更清晰。
for 语句
掌握 for 循环语句,让程序具备重复执行能力
for
是 JavaScript 提供的另一种循环控制的话句,它和 while
只是语法上存在差异。
for语句的基本使用
实现循环的 3 要素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <script > for (let i = 1 ; i <= 6 ; i++) { document .write (`<h${i} >循环控制,即重复执行<h${i} >` ) } </script >
变化量和死循环,for
循环和 while
一样,如果不合理设置增量和终止条件,便会产生死循环。
跳出和终止循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <script > for (let i = 1 ; i <= 5 ; i++) { if (i === 3 ) { continue } console .log (i) } for (let i = 1 ; i <= 5 ; i++) { if (i === 3 ) { break } console .log (i) } </script >
结论:
JavaScript
提供了多种语句来实现循环控制,但无论使用哪种语句都离不开循环的3个特征,即起始值、变化量、终止条件,做为初学者应着重体会这3个特征,不必过多纠结三种语句的区别。
起始值、变化量、终止条件,由开发者根据逻辑需要进行设计,规避死循环的发生。
当如果明确了循环的次数的时候推荐使用for
循环,当不明确循环的次数的时候推荐使用while
循环
注意:for
的语法结构更简洁,故 for
循环的使用频次会更多。
循环嵌套 利用循环的知识来对比一个简单的天文知识,我们知道地球在自转的同时也在围绕太阳公转,如果把自转和公转都看成是循环的话,就相当于是循环中又嵌套了另一个循环。
实际上 JavaScript 中任何一种循环语句都支持循环的嵌套,如下代码所示:
1 2 3 4 5 6 7 8 // 1. 外面的循环 记录第n天 for (let i = 1; i < 4; i++) { document.write(`第${i}天 <br > `) // 2. 里层的循环记录 几个单词 for (let j = 1; j < 6; j++) { document.write(`记住第${j}个单词<br > `) } }
记住,外层循环循环一次,里层循环循环全部
倒三角 1 2 3 4 5 6 7 8 for (let i = 1 ; i <= 5 ; i++) { for (let j = 1 ; j <= i; j++) { document .write ('★' ) } document .write ('<br>' ) }
九九乘法表 样式css
1 2 3 4 5 6 7 8 9 10 11 12 span { display : inline-block; width : 100px ; padding : 5px 10px ; border : 1px solid pink; margin : 2px ; border-radius : 5px ; box-shadow : 2px 2px 2px rgba (255 , 192 , 203 , .4 ); background-color : rgba (255 , 192 , 203 , .1 ); text-align : center; color : hotpink; }
javascript
1 2 3 4 5 6 7 8 9 10 11 for (let i = 1 ; i <= 9 ; i++) { for (let j = 1 ; j <= i; j++) { document .write (` <div> ${j} x ${i} = ${j * i} </div> ` ) } document .write ('<br>' ) }
数组
知道什么是数组及其应用的场景,掌握数组声明及访问的语法。
数组是什么? 数组: (Array)是一种可以按顺序保存数据的数据类型
使用场景: 如果有多个数据可以用数组保存起来,然后放到一个变量中,管理非常方便
数组的基本使用 定义数组和数组单元 1 2 3 4 5 6 7 8 <script > let classes = ['小明' , '小刚' , '小红' , '小丽' , '小米' ] </script >
通过 []
定义数组,数据中可以存放真正的数据,如小明、小刚、小红等这些都是数组中的数据,我们这些数据称为数组单元,数组单元之间使用英文逗号分隔。
访问数组和数组索引 使用数组存放数据并不是最终目的,关键是能够随时的访问到数组中的数据(单元)。其实 JavaScript 为数组中的每一个数据单元都编了号,通过数据单元在数组中的编号便可以轻松访问到数组中的数据单元了。
我们将数据单元在数组中的编号称为索引值,也有人称其为下标。
索引值实际是按着数据单元在数组中的位置依次排列的,注意是从 0
开始的,如下图所示:
观察上图可以数据单元【小明】对应的索引值为【0】,数据单元【小红】对应的索引值为【2】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <script > let classes = ['小明' , '小刚' , '小红' , '小丽' , '小米' ] document .write (classes[0 ]) document .write (classes[1 ]) document .write (classes[4 ]) document .write (classes[3 ]) classes[3 ] = '小小丽' document .wirte (classes[3 ]); </script >
数据单元值类型 数组做为数据的集合,它的单元值可以是任意数据类型
1 2 3 4 5 6 7 8 9 10 <script > let list = ['HTML' , 'CSS' , 'JavaScript' ] let scores = [78 , 84 , 70 , 62 , 75 ] let mixin = [true , 1 , false , 'hello' ] </script >
数组长度属性 重申一次,数组在 JavaScript 中并不是新的数据类型,它属于对象类型。
1 2 3 4 5 6 <script > let arr = ['html' , 'css' , 'javascript' ] console .log (arr.length ) </script >
操作数组 数组做为对象数据类型,不但有 length
属性可以使用,还提供了许多方法:
push 动态向数组的尾部添加一个单元
unshift 动态向数组头部添加一个单元
pop 删除最后一个单元
shift 删除第一个单元
splice 动态删除任意单元
使用以上4个方法时,都是直接在原数组上进行操作,即成功调任何一个方法,原数组都跟着发生相应的改变。并且在添加或删除单元时 length
并不会发生错乱。
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 > let arr = ['html' , 'css' , 'javascript' ] arr.push ('Nodejs' ) console .log (arr) arr.push ('Vue' ) arr.unshift ('VS Code' ) console .log (arr) arr.splice (2 , 1 ) console .log (arr) arr.pop () console .log (arr) arr.shift () console .log (arr) </script >
作业错题
JavaScript 基础 - 第4天笔记
理解封装的意义,能够通过函数的声明实现逻辑的封装,知道对象数据类型的特征,结合数学对象实现简单计算功能。
理解函数的封装的特征
掌握函数声明的语法
理解什么是函数的返回值
知道并能使用常见的内置函数
函数
理解函数的封装特性,掌握函数的语法规则
声明和调用 函数可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行这些被“包裹”的代码逻辑,这么做的优势是有利于精简代码方便复用。
声明(定义) 声明(定义)一个完整函数包括关键字、函数名、形式参数、函数体、返回值5个部分
调用 声明(定义)的函数必须调用才会真正被执行,使用 ()
调用函数。
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" > <title > JavaScript 基础 - 声明和调用</title > </head > <body > <script > function sayHi ( ) { console .log ('嗨~' ) } sayHi () sayHi () </script > </body > </html >
注:函数名的命名规则与变量是一致的,并且尽量保证函数名的语义。
小案例: 小星星
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <script> function sayHi ( ) { document .write (`*<br>` ) document .write (`**<br>` ) document .write (`***<br>` ) document .write (`****<br>` ) document .write (`*****<br>` ) document .write (`******<br>` ) document .write (`*******<br>` ) document .write (`********<br>` ) document .write (`*********<br>` ) } sayHi () sayHi () sayHi () sayHi () sayHi () </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 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 函数参数</title > </head > <body > <script > function sayHi (name ) { console .log (name) console .log ('嗨~' + name) } sayHi ('小明' ) sayHi ('小红' ) </script > </body > </html >
总结:
声明(定义)函数时的形参没有数量限制,当有多个形参时使用 ,
分隔
调用函数传递的实参要与形参的顺序一致
形参和实参 形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)
实参:调用函数时写在函数名右边小括号里的叫实参(实际上的参数)
形参可以理解为是在这个函数内声明的变量(比如 num1 = 10)实参可以理解为是给这个变量赋值
开发中尽量保持形参和实参个数一致
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 函数参数</title > </head > <body > <script > function count (x, y ) { console .log (x + y); } count (10 , 5 ); </script > </body > </html >
返回值 函数的本质是封装(包裹),函数体内的逻辑执行完毕后,函数外部如何获得函数内部的执行结果呢?要想获得函数内部逻辑的执行结果,需要通过 return
这个关键字,将内部执行结果传递到函数外部,这个被传递到外部的结果就是返回值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 函数返回值</title > </head > <body > <script > function count (a, b ) { let s = a + b return s } let total = count (5 , 12 ) </script > </body > </html >
总结:
在函数体中使用return 关键字能将内部的执行结果交给函数外部使用
函数内部只能出现1 次 return,并且 return 下一行代码不会再被执行,所以return 后面的数据不要换行写
return会立即结束当前函数
函数可以没有return,这种情况默认返回值为 undefined
作用域 通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
全局作用域 作用于所有代码执行的环境(整个 script 标签内部)或者一个独立的 js 文件
处于全局作用域内的变量,称为全局变量
局部作用域 作用于函数内的代码环境,就是局部作用域。 因为跟函数有关系,所以也称为函数作用域。
处于局部作用域内的变量称为局部变量
如果函数内部,变量没有声明,直接赋值,也当全局变量看,但是强烈不推荐
但是有一种情况,函数内部的形参可以看做是局部变量。
匿名函数 函数可以分为具名函数和匿名函数
匿名函数:没有名字的函数,无法直接使用。
函数表达式 1 2 3 4 5 6 let fn = function ( ) { console .log ('函数表达式' ) } fn ()
立即执行函数 1 2 (function ( ){ xxx })(); (function ( ){xxxx}());
无需调用,立即执行,其实本质已经调用了
多个立即执行函数之间用分号隔开
在能够访问到的情况下 先局部 局部没有在找全局
作业错题
JavaScript 基础 - 第5天
知道对象数据类型的特征,能够利用数组对象渲染页面
理解什么是对象,掌握定义对象的语法
掌握数学对象的使用
对象
对象是 JavaScript 数据类型的一种,之前已经学习了数值类型、字符串类型、布尔类型、undefined。对象数据类型可以被理解成是一种数据集合。它由属性和方法两部分构成。
语法 声明一个对象类型的变量与之前声明一个数值或字符串类型的变量没有本质上的区别。
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" > <title > JavaScript 基础 - 对象语法</title > </head > <body > <script > let str = 'hello world!' let num = 199 let user = {} </script > </body > </html >
属性和访问 数据描述性的信息称为属性,如人的姓名、身高、年龄、性别等,一般是名词性的。
属性都是成 对出现的,包括属性名和值,它们之间使用英文 :
分隔
多个属性之间使用英文 ,
分隔
属性就是依附在对象上的变量
属性名可以使用 ""
或 ''
,一般情况下省略,除非名称遇到特殊符号如空格、中横线等
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" > <title > JavaScript 基础 - 对象语法</title > </head > <body > <script > let person = { name : '小明' , age : 18 , stature : 185 , gender : '男' , } </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 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 对象语法</title > </head > <body > <script > let person = { name : '小明' , age : 18 , stature : 185 , gender : '男' , }; console .log (person.name ) console .log (person.gender ) console .log (person['stature' ]) console .log (person.stature ) </script > </body > </html >
扩展:也可以动态为对象添加属性,动态添加与直接定义是一样的,只是语法上更灵活。
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" > <title > JavaScript 基础 - 对象语法</title > </head > <body > <script > let user = {} user.name = '小明' user['age' ] = 18 </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 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 对象方法</title > </head > <body > <script > let person = { name : '小红' , age : 18 , singing : function ( ) { console .log ('两只老虎,两只老虎,跑的快,跑的快...' ) }, run : function ( ) { console .log ('我跑的非常快...' ) } } </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 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 对象方法</title > </head > <body > <script > let person = { name : '小红' , age : 18 , singing : function ( ) { console .log ('两只老虎,两只老虎,跑的快,跑的快...' ) }, run : function ( ) { console .log ('我跑的非常快...' ) } } person.singing () person.run () </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 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > JavaScript 基础 - 对象方法</title > </head > <body > <script > let user = {} user.name = '小明' user.['age' ] = 18 user.move = function ( ) { console .log ('移动一点距离...' ) } </script > </body > </html >
注:无论是属性或是方法,同一个对象中出现名称一样的,后面的会覆盖前面的。
null null 也是 JavaScript 中数据类型的一种,通常只用它来表示不存在的对象。使用 typeof 检测类型它的类型时,结果为 object
。
遍历对象 1 2 3 4 5 6 7 let obj = { uname : 'pink' } for (let k in obj) { }
for in 不提倡遍历数组 因为 k 是 字符串
内置对象 回想一下我们曾经使用过的 console.log
,console
其实就是 JavaScript 中内置的对象,该对象中存在一个方法叫 log
,然后调用 log
这个方法,即 console.log()
。
除了 console
对象外,JavaScritp 还有其它的内置的对象
Math Math
是 JavaScript 中内置的对象,称为数学对象,这个对象下即包含了属性,也包含了许多的方法。
属性
方法
Math.random,生成 0 到 1 间的随机数
1 2 3 Math .round (5.46539 )Math .round (4.849 )
1 2 Math .max (10 , 21 , 7 , 24 , 13 )
1 2 Math .min (24 , 18 , 6 , 19 , 21 )
1 2 3 Math .pow (4 , 2 ) Math .pow (2 , 3 )
数学对象提供了比较多的方法,这里不要求强记,通过演示数学对象的使用,加深对对象的理解。
复习:
splice() 方法用于添加或删除数组中的元素。
注意: 这种方法会改变原始数组。
删除数组:
splice(起始位置, 删除的个数)
比如:1
1 2 3 let arr = ['red' , 'green' , 'blue' ]arr.splice (1 ,1 ) console .log (arr)
添加元素
splice(起始位置,删除个数,添加数组元素)
1 2 3 4 5 let arr = ['red' , 'green' , 'blue' ]arr.splice (1 , 0 , 'pink' , 'hotpink' ) console .log (arr)
Web APIs - 第1天笔记
了解 DOM 的结构并掌握其基本的操作,体验 DOM 的在开发中的作用
知道 ECMAScript 与 JavaScript 的关系
了解 DOM 的相关概念及DOM 的本质是一个对象
掌握查找节点的基本方法
掌握节点属性和文本的操作
能够使用间歇函数创建定时任务
介绍
知道 ECMAScript 与 JavaScript 的关系,Web APIs 是浏览器扩展的功能。
严格意义上讲,我们在 JavaScript 阶段学习的知识绝大部分属于 ECMAScript 的知识体系,ECMAScript 简称 ES 它提供了一套语言标准规范,如变量、数据类型、表达式、语句、函数等语法规则都是由 ECMAScript 规定的。浏览器将 ECMAScript 大部分的规范加以实现,并且在此基础上又扩展一些实用的功能,这些被扩展出来的内容我们称为 Web APIs。
ECMAScript 运行在浏览器中然后再结合 Web APIs 才是真正的 JavaScript,Web APIs 的核心是 DOM 和 BOM。
扩展阅读:ECMAScript 规范在不断的更新中,存在多个不同的版本,早期的版本号采用数字顺序编号如 ECMAScript3、ECMAScript5,后来由于更新速度较快便采用年份做为版本号,如 ECMAScript2017、ECMAScript2018 这种格式,ECMAScript6 是 2015 年发布的,常叫做 EMCAScript2015。
关于 JavaScript 历史的扩展阅读 。
知道 DOM 相关的概念,建立对 DOM 的初步认识,学习 DOM 的基本操作,体会 DOM 的作用
DOM(Document Object Model)是将整个 HTML 文档的每一个标签元素视为一个对象,这个对象下包含了许多的属性和方法,通过操作这些属性或者调用这些方法实现对 HTML 的动态更新,为实现网页特效以及用户交互提供技术支撑。
简言之 DOM 是用来动态修改 HTML 的,其目的是开发网页特效及用户交互。
观察一个小例子:
上述的例子中当用户分分别点击【开始】或【结束】按钮后,通过右侧调试窗口可以观察到 html 标签的内容在不断的发生改变,这便是通过 DOM 实现的。
概念 DOM 树 1 2 3 4 5 6 7 8 9 10 11 12 13 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > 标题</title > </head > <body > 文本 <a href ="" > 链接名</a > <div id ="" class ="" > 文本</div > </body > </html >
如下图所示,将 HTML 文档以树状结构直观的表现出来,我们称之为文档树或 DOM 树,文档树直观的体现了标签与标签之间的关系。
DOM 节点 节点是文档树的组成部分,每一个节点都是一个 DOM 对象 ,主要分为元素节点、属性节点、文本节点等。
【元素节点】其实就是 HTML 标签,如上图中 head
、div
、body
等都属于元素节点。
【属性节点】是指 HTML 标签中的属性,如上图中 a
标签的 href
属性、div
标签的 class
属性。
【文本节点】是指 HTML 标签的文字内容,如 title
标签中的文字。
【根节点】特指 html
标签。
其它…
document document
是 JavaScript 内置的专门用于 DOM 的对象,该对象包含了若干的属性和方法,document
是学习 DOM 的核心。
1 2 3 4 5 6 7 8 9 10 11 12 13 <script > console .log (document .documentElement ); console .log (document .body ); document .write ('Hello World!' ); </script >
上述列举了 document
对象的部分属性和方法,我们先对 document
有一个整体的认识。
获取DOM对象
querySelector 满足条件的第一个元素
querySelectorAll 满足条件的元素集合 返回伪数组
了解其他方式
getElementById
getElementsByTagName
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > DOM - 查找节点</title > </head > <body > <h3 > 查找元素类型节点</h3 > <p > 从整个 DOM 树中查找 DOM 节点是学习 DOM 的第一个步骤。</p > <ul > <li > 元素</li > <li > 元素</li > <li > 元素</li > <li > 元素</li > </ul > <script > const p = document .querySelector ('p' ) const lis = document .querySelectorAll ('li' ) </script > </body > </html >
总结:
document.getElementById 专门获取元素类型节点,根据标签的 id
属性查找
任意 DOM 对象都包含 nodeType 属性,用来检检测节点类型
操作元素内容 通过修改 DOM 的文本内容,动态改变网页的内容。
innerText
将文本内容添加/更新到任意标签位置,文本中包含的标签不会被解析。
1 2 3 4 5 6 <script > const intro = document .querySelector ('.intro' ) </script >
innerHTML
将文本内容添加/更新到任意标签位置,文本中包含的标签会被解析。
1 2 3 4 5 6 <script > const intro = document .querySelector ('.intro' ) intro.innerHTML = '嗨~ 我叫韩梅梅!' intro.innerHTML = '<h4>嗨~ 我叫韩梅梅!</h4>' </script >
总结:如果文本内容中包含 html
标签时推荐使用 innerHTML
,否则建议使用 innerText
属性。
##操作元素属性
有3种方式可以实现对属性的修改:
常用属性修改
直接能过属性名修改,最简洁的语法
1 2 3 4 5 6 7 8 <script > const pic = document .querySelector ('.pic' ) pic.src = './images/lion.webp' pic.width = 400 ; pic.alt = '图片不见了...' </script >
控制样式属性
应用【修改样式】,通过修改行内样式 style
属性,实现对样式的动态修改。
通过元素节点获得的 style
属性本身的数据类型也是对象,如 box.style.color
、box.style.width
分别用来获取元素节点 CSS 样式的 color
和 width
的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > 练习 - 修改样式</title > </head > <body > <div class ="box" > 随便一些文本内容</div > <script > const box = document .querySelector ('.intro' ) box.style .color = 'red' box.style .width = '300px' box.style .backgroundColor = 'pink' </script > </body > </html >
任何标签都有 style
属性,通过 style
属性可以动态更改网页标签的样式,如要遇到 css
属性中包含字符 -
时,要将 -
去掉并将其后面的字母改成大写,如 background-color
要写成 box.style.backgroundColor
操作类名(className) 操作CSS
如果修改的样式比较多,直接通过style属性修改比较繁琐,我们可以通过借助于css类名的形式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > 练习 - 修改样式</title > <style > .pink { background : pink; color : hotpink; } </style > </head > <body > <div class ="box" > 随便一些文本内容</div > <script > const box = document .querySelector ('.intro' ) box.className = 'pink' </script > </body > </html >
注意:
1.由于class是关键字, 所以使用className去代替
2.className是使用新值换旧值, 如果需要添加一个类,需要保留之前的类名
通过 classList 操作类控制CSS
为了解决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 <!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 > div { width : 200px ; height : 200px ; background-color : pink; } .active { width : 300px ; height : 300px ; background-color : hotpink; margin-left : 100px ; } </style > </head > <body > <div class ="one" > </div > <script > let box = document .querySelector ('div' ) box.classList .toggle ('one' ) </script > </body > </html >
操作表单元素属性 表单很多情况,也需要修改属性,比如点击眼睛,可以看到密码,本质是把表单类型转换为文本框
正常的有属性有取值的跟其他的标签属性没有任何区别
获取:DOM对象.属性名
设置:DOM对象.属性名= 新值
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 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > Document</title > </head > <body > <input type ="text" value ="请输入" > <button disabled > 按钮</button > <input type ="checkbox" name ="" id ="" class ="agree" > <script > let input = document .querySelector ('input' ) input.value = '小米手机' input.type = 'password' let btn = document .querySelector ('button' ) btn.disabled = false let checkbox = document .querySelector ('.agree' ) checkbox.checked = false </script > </body > </html >
自定义属性 标准属性: 标签天生自带的属性 比如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 21 22 23 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta http-equiv ="X-UA-Compatible" content ="IE=edge" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > Document</title > </head > <body > <div data-id ="1" > 自定义属性 </div > <script > let div = document .querySelector ('div' ) console .log (div.dataset .id ) </script > </body > </html >
间歇函数
知道间歇函数的作用,利用间歇函数创建定时任务。
setInterval
是 JavaScript 中内置的函数,它的作用是间隔固定的时间自动重复执行另一个函数,也叫定时器函数。
1 2 3 4 5 6 7 8 9 10 <script > function repeat ( ) { console .log ('不知疲倦的执行下去....' ) } setInterval (repeat, 1000 ) </script >
今日单词
单词
说明
解释
setInterval
定时器
setInterval(repeat, 1000)
作业错题
Web APIs - 第2天
学会通过为DOM注册事件来实现可交互的网页特效。
能够判断函数运行的环境并确字 this 所指代的对象
理解事件的作用,知道应用事件的 3 个步骤
学习会为 DOM 注册事件,实现简单可交互的网页特效。
事件 事件是编程语言中的术语,它是用来描述程序的行为或状态的,一旦行为或状态发生改变,便立即调用一个函数。
例如:用户使用【鼠标点击】网页中的一个按钮、用户使用【鼠标拖拽】网页中的一张图片
事件监听 结合 DOM 使用事件时,需要为 DOM 对象添加事件监听,等待事件发生(触发)时,便立即调用一个函数。
addEventListener
是 DOM 对象专门用来添加事件监听的方法,它的两个参数分别为【事件类型】和【事件回调】。
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 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > 事件监听</title > </head > <body > <h3 > 事件监听</h3 > <p id ="text" > 为 DOM 元素添加事件监听,等待事件发生,便立即执行一个函数。</p > <button id ="btn" > 点击改变文字颜色</button > <script > const btn = document .querySelector ('#btn' ) btn.addEventListener ('click' , function ( ) { console .log ('等待事件被触发...' ) let text = document .getElementById ('text' ) text.style .color = 'red' }) </script > </body > </html >
完成事件监听分成3个步骤:
获取 DOM 元素
通过 addEventListener
方法为 DOM 节点添加事件监听
等待事件触发,如用户点击了某个按钮时便会触发 click
事件类型
事件触发后,相对应的回调函数会被执行
大白话描述:所谓的事件无非就是找个机会(事件触发)调用一个函数(回调函数)。
事件类型 click
译成中文是【点击】的意思,它的含义是监听(等着)用户鼠标的单击操作,除了【单击】还有【双击】dblclick
1 2 3 4 5 6 7 8 9 10 11 <script > btn.addEventListener ('dblclick' , function ( ) { console .log ('等待事件被触发...' ); const text = document .querySelector ('.text' ) text.style .color = 'red' }) </script >
结论:【事件类型】决定了事件被触发的方式,如 click
代表鼠标单击,dblclick
代表鼠标双击。
事件处理程序 addEventListener
的第2个参数是函数,这个函数会在事件被触发时立即被调用,在这个函数中可以编写任意逻辑的代码,如改变 DOM 文本颜色、文本内容等。
1 2 3 4 5 6 7 8 9 10 11 12 <script > btn.addEventListener ('dblclick' , function ( ) { console .log ('等待事件被触发...' ) const text = document .querySelector ('.text' ) text.style .color = 'red' text.style .fontSize = '20px' }) </script >
结论:【事件处理程序】决定了事件触发后应该执行的逻辑。
事件类型 将众多的事件类型分类可分为:鼠标事件、键盘事件、表单事件、焦点事件等,我们逐一展开学习。
鼠标事件 鼠标事件是指跟鼠标操作相关的事件,如单击、双击、移动等。
`mouseenter 监听鼠标是否移入 DOM 元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <body > <h3 > 鼠标事件</h3 > <p > 监听与鼠标相关的操作</p > <hr > <div class ="box" > </div > <script > const box = document .querySelector ('.box' ); box.addEventListener ('mouseenter' , function ( ) { this .innerText = '鼠标移入了...' ; this .style .cursor = 'move' ; }) </script > </body >
`mouseleave 监听鼠标是否移出 DOM 元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <body > <h3 > 鼠标事件</h3 > <p > 监听与鼠标相关的操作</p > <hr > <div class ="box" > </div > <script > const box = document .querySelector ('.box' ); box.addEventListener ('mouseleave' , function ( ) { this .innerText = '鼠标移出了...' ; }) </script > </body >
键盘事件 keydown 键盘按下触发 keyup 键盘抬起触发
焦点事件 focus 获得焦点
blur 失去焦点
文本框输入事件 input
事件对象 任意事件类型被触发时与事件相关的信息会被以对象的形式记录下来,我们称这个对象为事件对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <body > <h3 > 事件对象</h3 > <p > 任意事件类型被触发时与事件相关的信息会被以对象的形式记录下来,我们称这个对象为事件对象。</p > <hr > <div class ="box" > </div > <script > const box = document .querySelector ('.box' ) box.addEventListener ('click' , function (e ) { console .log ('任意事件类型被触发后,相关信息会以对象形式被记录下来...' ); console .log (e) }) </script > </body >
事件回调函数的【第1个参数】即所谓的事件对象,通常习惯性的将这个对数命名为 event
、ev
、ev
。
接下来简单看一下事件对象中包含了哪些有用的信息:
ev.type
当前事件的类型
ev.clientX/Y
光标相对浏览器窗口的位置
ev.offsetX/Y
光标相于当前 DOM 元素的位置
注:在事件回调函数内部通过 window.event 同样可以获取事件对象。
环境对象
能够分析判断函数运行在不同环境中 this 所指代的对象。
环境对象指的是函数内部特殊的变量 this
,它代表着当前函数运行时所处的环境。
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 > function sayHi ( ) { console .log (this ); } let user = { name : '张三' , sayHi : sayHi } let person = { name : '李四' , sayHi : sayHi } sayHi () window .sayHi () user.sayHi () person.sayHi () </script >
结论:
this
本质上是一个变量,数据类型为对象
函数的调用方式不同 this
变量的值也不同
【谁调用 this
就是谁】是判断 this
值的粗略规则
函数直接调用时实际上 window.sayHi()
所以 this
的值为 window
回调函数 如果将函数 A 做为参数传递给函数 B 时,我们称函数 A 为回调函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <script > function foo (arg ) { console .log (arg); } foo (10 ); foo ('hello world!' ); foo (['html' , 'css' , 'javascript' ]); function bar ( ) { console .log ('函数也能当参数...' ); } foo (bar); </script >
函数 bar
做参数传给了 foo
函数,bar
就是所谓的回调函数了!!!
我们回顾一下间歇函数 setInterval
1 2 3 4 5 6 7 <script > function fn ( ) { console .log ('我是回调函数...' ); } setInterval (fn, 1000 ); </script >
fn
函数做为参数传给了 setInterval
,这便是回调函数的实际应用了,结合刚刚学习的函数表达式上述代码还有另一种更常见写法。
1 2 3 4 5 6 <script > setInterval (function ( ) { console .log ('我是回调函数...' ); }, 1000 ); </script >
结论:
回调函数本质还是函数,只不过把它当成参数使用
使用匿名函数做为回调函数比较常见
Web APIs - 第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 <body > <h3 > 事件流</h3 > <p > 事件流是事件在执行时的底层机制,主要体现在父子盒子之间事件的执行上。</p > <div class ="outer" > <div class ="inner" > <div class ="child" > </div > </div > </div > <script > const outer = document .querySelector ('.outer' ); const inner = document .querySelector ('.inner' ); const child = document .querySelector ('.child' ); document .documentElement .addEventListener ('click' , function ( ) { console .log ('html...' ) }) document .body .addEventListener ('click' , function ( ) { console .log ('body...' ) }) outer.addEventListener ('click' , function ( ) { console .log ('outer...' ) }) outer.addEventListener ('click' , function ( ) { console .log ('inner...' ) }) outer.addEventListener ('click' , function ( ) { console .log ('child...' ) }) </script > </body >
执行上述代码后发现,当单击事件触发时,其祖先元素的单击事件也【相继触发】,这是为什么呢?
结合事件流的特征,我们知道当某个元素的事件被触发时,事件总是会先经过其祖先才能到达当前元素,然后再由当前元素向祖先传递,事件在流动的过程中遇到相同的事件便会被触发。
再来关注一个细节就是事件相继触发的【执行顺序】,事件的执行顺序是可控制的,即可以在捕获阶段被执行,也可以在冒泡阶段被执行。
如果事件是在冒泡阶段执行的,我们称为冒泡模式,它会先执行子盒子事件再去执行父盒子事件,默认是冒泡模式。
如果事件是在捕获阶段执行的,我们称为捕获模式,它会先执行父盒子事件再去执行子盒子事件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <body > <h3 > 事件流</h3 > <p > 事件流是事件在执行时的底层机制,主要体现在父子盒子之间事件的执行上。</p > <div class ="outer" > <div class ="inner" > </div > </div > <script > const outer = document .querySelector ('.outer' ) const inner = document .querySelector ('.inner' ) outer.addEventListener ('click' , function ( ) { console .log ('outer...' ) }, true ) outer.addEventListener ('click' , function ( ) { console .log ('inner...' ) }, true ) </script > </body >
结论:
addEventListener
第3个参数决定了事件是在捕获阶段触发还是在冒泡阶段触发
addEventListener
第3个参数为 true
表示捕获阶段触发,false
表示冒泡阶段触发,默认值为 false
事件流只会在父子元素具有相同事件类型时才会产生影响
绝大部分场景都采用默认的冒泡模式(其中一个原因是早期 IE 不支持捕获)
阻止冒泡 阻止冒泡是指阻断事件的流动,保证事件只在当前元素被执行,而不再去影响到其对应的祖先元素。
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 <body > <h3 > 阻止冒泡</h3 > <p > 阻止冒泡是指阻断事件的流动,保证事件只在当前元素被执行,而不再去影响到其对应的祖先元素。</p > <div class ="outer" > <div class ="inner" > <div class ="child" > </div > </div > </div > <script > const outer = document .querySelector ('.outer' ) const inner = document .querySelector ('.inner' ) const child = document .querySelector ('.child' ) outer.addEventListener ('click' , function ( ) { console .log ('outer...' ) }) inner.addEventListener ('click' , function (ev ) { console .log ('inner...' ) ev.stopPropagation () }) child.addEventListener ('click' , function (ev ) { console .log ('child...' ) ev.stopPropagation () }) </script > </body >
结论:事件对象中的 ev.stopPropagation
方法,专门用来阻止事件冒泡。
鼠标经过事件:
mouseover 和 mouseout 会有冒泡效果
mouseenter 和 mouseleave 没有冒泡效果 (推荐)
事件委托 事件委托是利用事件流的特征解决一些现实开发需求的知识技巧,主要的作用是提升程序效率。
大量的事件监听是比较耗费性能的,如下代码所示
1 2 3 4 5 6 7 8 9 10 11 <script > const buttons = document .querySelectorAll ('table button' ); for (let i = 0 ; i <= buttons.length ; i++) { buttons.addEventListener ('click' , function ( ) { }) } </script >
利用事件流的特征,可以对上述的代码进行优化,事件的的冒泡模式总是会将事件流向其父元素的,如果父元素监听了相同的事件类型,那么父元素的事件就会被触发并执行,正是利用这一特征对上述代码进行优化,如下代码所示:
1 2 3 4 5 6 7 8 9 10 <script > let buttons = document .querySelectorAll ('table button' ); let parents = document .querySelector ('table' ); parents.addEventListener ('click' , function ( ) { console .log ('点击任意子元素都会触发事件...' ); }) </script >
我们的最终目的是保证只有点击 button 子元素才去执行事件的回调函数,如何判断用户点击是哪一个子元素呢?
事件对象中的属性 target
或 srcElement
属性表示真正触发事件的元素,它是一个元素类型的节点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <script > const buttons = document .querySelectorAll ('table button' ) const parents = document .querySelector ('table' ) parents.addEventListener ('click' , function (ev ) { if (ev.target .tagName === 'BUTTON' ) { } }) </script >
优化过的代码只对祖先元素添加事件监听,相比对 10000 个元素添加事件监听执行效率要高许多!!!
其他事件 页面加载事件 加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件
有些时候需要等页面资源全部处理完了做一些事情
事件名:load
监听页面所有资源加载完毕:
1 2 3 window .addEventListener ('load' , function ( ) { })
元素滚动事件 滚动条在滚动的时候持续触发的事件
1 2 3 window .addEventListener ('scroll' , function ( ) { })
页面尺寸事件 会在窗口尺寸改变的时候触发事件:
1 2 3 window .addEventListener ('resize' , function ( ) { })
元素尺寸与位置 获取元素的自身宽高、包含元素自身设置的宽高、padding、border
offsetWidth和offsetHeight
获取出来的是数值,方便计算
注意: 获取的是可视宽高, 如果盒子是隐藏的,获取的结果是0
Web APIs - 第4天
进一步学习 DOM 相关知识,实现可交互的网页特效
能够插入、删除和替换元素节点
能够依据元素节点关系查找节点
日期对象 掌握 Date 日期对象的使用,动态获取当前计算机的时间。
ECMAScript 中内置了获取系统时间的对象 Date,使用 Date 时与之前学习的内置对象 console 和 Math 不同,它需要借助 new 关键字才能使用。
实例化 1 2 3 4 5 6 7 8 9 const date = new Date ('2020-05-01' ) console .log (typeof date)
方法 1 2 3 4 5 6 const date = new Date ();const year = date.getFullYear (); const month = date.getMonth ();
getFullYear 获取四位年份
getMonth 获取月份,取值为 0 ~ 11
getDate 获取月份中的每一天,不同月份取值也不相同
getDay 获取星期,取值为 0 ~ 6
getHours 获取小时,取值为 0 ~ 23
getMinutes 获取分钟,取值为 0 ~ 59
getSeconds 获取秒,取值为 0 ~ 59
时间戳 时间戳是指1970年01月01日00时00分00秒起至现在的总秒数或毫秒数,它是一种特殊的计量时间的方式。
注:ECMAScript 中时间戳是以毫秒计的。
1 2 3 4 5 6 7 8 9 const date = new Date () console .log (date.getTime ()) console .log (+new Date ()) console .log (Date .now ())
获取时间戳的方法,分别为 getTime 和 Date.now 和 +new Date()
DOM 节点
掌握元素节点创建、复制、插入、删除等操作的方法,能够依据元素节点的结构关系查找节点
回顾之前 DOM 的操作都是针对元素节点的属性或文本的,除此之外也有专门针对元素节点本身的操作,如插入、复制、删除、替换等。
插入节点 在已有的 DOM 节点中插入新的 DOM 节点时,需要关注两个关键因素:首先要得到新的 DOM 节点,其次在哪个位置插入这个节点。
如下代码演示:
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 > <h3 > 插入节点</h3 > <p > 在现有 dom 结构基础上插入新的元素节点</p > <hr > <div class ="box" > </div > <button class ="btn" > 插入节点</button > <script > const btn = document .querySelector ('.btn' ) btn.addEventListener ('click' , function ( ) { const p = document .createElement ('p' ) p.innerText = '创建的新的p标签' p.className = 'info' const p2 = document .querySelector ('p' ).cloneNode (true ) p2.style .color = 'red' document .querySelector ('.box' ).appendChild (p) document .querySelector ('.box' ).appendChild (p2) }) </script > </body >
结论:
createElement
动态创建任意 DOM 节点
cloneNode
复制现有的 DOM 节点,传入参数 true 会复制所有子节点
appendChild
在末尾(结束标签前)插入节点
再来看另一种情形的代码演示:
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 <body > <h3 > 插入节点</h3 > <p > 在现有 dom 结构基础上插入新的元素节点</p > <hr > <button class ="btn1" > 在任意节点前插入</button > <ul > <li > HTML</li > <li > CSS</li > <li > JavaScript</li > </ul > <script > const btn1 = document .querySelector ('.btn1' ) btn1.addEventListener ('click' , function ( ) { const relative = document .querySelector ('li:nth-child(2)' ) const li1 = document .createElement ('li' ) li1.style .color = 'red' li1.innerText = 'Web APIs' const li2 = document .querySelector ('li:first-child' ).cloneNode (true ) li2.style .color = 'blue' document .querySelector ('ul' ).insertBefore (li1, relative) document .querySelector ('ul' ).insertBefore (li2, relative) }) </script > </body >
结论:
createElement
动态创建任意 DOM 节点
cloneNode
复制现有的 DOM 节点,传入参数 true 会复制所有子节点
insertBefore
在父节点中任意子节点之前插入新节点
删除节点 删除现有的 DOM 节点,也需要关注两个因素:首先由父节点删除子节点,其次是要删除哪个子节点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <body > <button > 删除节点</button > <ul > <li > HTML</li > <li > CSS</li > <li > Web APIs</li > </ul > <script > const btn = document .querySelector ('button' ) btn.addEventListener ('click' , function ( ) { let ul = document .querySelector ('ul' ) let lis = document .querySelectorAll ('li' ) ul.removeChild (lis[0 ]) }) </script > </body >
结论:removeChild
删除节点时一定是由父子关系。
查找节点 DOM 树中的任意节点都不是孤立存在的,它们要么是父子关系,要么是兄弟关系,不仅如此,我们可以依据节点之间的关系查找节点。
父子关系 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <body > <button class ="btn1" > 所有的子节点</button > <ul > <li > HTML</li > <li > CSS</li > <li > JavaScript 基础</li > <li > Web APIs</li > </ul > <script > const btn1 = document .querySelector ('.btn1' ) btn1.addEventListener ('click' , function ( ) { const ul = document .querySelector ('ul' ) console .log (ul.childNodes ) console .log (ul.children ) }) </script > </body >
结论:
childNodes
获取全部的子节点,回车换行会被认为是空白文本节点
children
只获取元素类型节点
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 <body > <table > <tr > <td width ="60" > 序号</td > <td > 课程名</td > <td > 难度</td > <td width ="80" > 操作</td > </tr > <tr > <td > 1</td > <td > <span > HTML</span > </td > <td > 初级</td > <td > <button > 变色</button > </td > </tr > <tr > <td > 2</td > <td > <span > CSS</span > </td > <td > 初级</td > <td > <button > 变色</button > </td > </tr > <tr > <td > 3</td > <td > <span > Web APIs</span > </td > <td > 中级</td > <td > <button > 变色</button > </td > </tr > </table > <script > const buttons = document .querySelectorAll ('table button' ) for (let i = 0 ; i < buttons.length ; i++) { buttons[i].addEventListener ('click' , function ( ) { this .parentNode .parentNode .style .color = 'red' }) } </script > </body >
结论:parentNode
获取父节点,以相对位置查找节点,实际应用中非常灵活。
兄弟关系 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <body > <ul > <li > HTML</li > <li > CSS</li > <li > JavaScript 基础</li > <li > Web APIs</li > </ul > <script > const lis = document .querySelectorAll ('ul li' ) for (let i = 0 ; i < lis.length ; i++) { lis[i].addEventListener ('click' , function ( ) { console .log (this .previousSibling ) console .log (this .nextSibling ) }) } </script > </body >
结论:
previousSibling
获取前一个节点,以相对位置查找节点,实际应用中非常灵活。
nextSibling
获取后一个节点,以相对位置查找节点,实际应用中非常灵活。
Web APIs - 第5天笔记
目标: 能够利用JS操作浏览器,具备利用本地存储实现学生就业表的能力
js组成 JavaScript的组成
ECMAScript:
规定了js基础语法核心知识。
比如:变量、分支语句、循环语句、对象等等
Web APIs :
DOM 文档对象模型, 定义了一套操作HTML文档的API
BOM 浏览器对象模型,定义了一套操作浏览器窗口的API
window对象 BOM (Browser Object Model ) 是浏览器对象模型
window对象是一个全局对象,也可以说是JavaScript中的顶级对象
像document、alert()、console.log()这些都是window的属性,基本BOM的属性和方法都是window的
所有通过var定义在全局作用域中的变量、函数都会变成window对象的属性和方法
window对象下的属性和方法调用的时候可以省略window
定时器-延迟函数 JavaScript 内置的一个用来让代码延迟执行的函数,叫 setTimeout
语法:
setTimeout 仅仅只执行一次,所以可以理解为就是把一段代码延迟执行, 平时省略window
间歇函数 setInterval : 每隔一段时间就执行一次, , 平时省略window
清除延时函数:
注意点
延时函数需要等待,所以后面的代码先执行
返回值是一个正整数,表示定时器的编号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <body > <script > let timerId = setTimeout (function ( ) { console .log ('我只执行一次' ) }, 3000 ) console .log (timerId) clearTimeout (timerId) </script > </body >
location对象 location (地址) 它拆分并保存了 URL 地址的各个组成部分, 它是一个对象
属性/方法
说明
href
属性,获取完整的 URL 地址,赋值时用于地址的跳转
search
属性,获取地址中携带的参数,符号 ?后面部分
hash
属性,获取地址中的啥希值,符号 # 后面部分
reload()
方法,用来刷新当前页面,传入参数 true 时表示强制刷新
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 > <form > <input type ="text" name ="search" > <button > 搜索</button > </form > <a href ="#/music" > 音乐</a > <a href ="#/download" > 下载</a > <button class ="reload" > 刷新页面</button > <script > console .log (location.href ) console .log (location.search ) console .log (location.hash ) const btn = document .querySelector ('.reload' ) btn.addEventListener ('click' , function ( ) { location.reload (true ) }) </script > </body >
navigator对象 navigator是对象,该对象下记录了浏览器自身的相关信息
常用属性和方法:
1 2 3 4 5 6 7 8 9 10 (function ( ) { const userAgent = navigator.userAgent const android = userAgent.match (/(Android);?[\s\/]+([\d.]+)?/ ) const iphone = userAgent.match (/(iPhone\sOS)\s([\d_]+)/ ) if (android || iphone) { location.href = 'http://m.itcast.cn' }})();
histroy对象 history (历史)是对象,主要管理历史记录, 该对象与浏览器地址栏的操作相对应,如前进、后退等
使用场景
history对象一般在实际开发中比较少用,但是会在一些OA 办公系统中见到。
常见方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <body > <button class ="back" > ←后退</button > <button class ="forward" > 前进→</button > <script > const forward = document .querySelector ('.forward' ) forward.addEventListener ('click' , function ( ) { history.go (1 ) }) const back = document .querySelector ('.back' ) back.addEventListener ('click' , function ( ) { history.go (-1 ) }) </script > </body >
本地存储(今日重点) 本地存储:将数据存储在本地浏览器中
常见的使用场景:
https://todomvc.com/examples/vanilla-es6/ 页面刷新数据不丢失
好处:
1、页面刷新或者关闭不丢失数据,实现数据持久化
2、容量较大,sessionStorage和 localStorage 约 5M 左右
localStorage(重点) 作用: 数据可以长期保留在本地浏览器中,刷新页面和关闭页面,数据也不会丢失
特性: 以键值对的形式存储,并且存储的是字符串, 省略了window
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 <!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 > 本地存储-localstorage</title > </head > <body > <script > localStorage .setItem ('age' , 18 ) console .log (typeof localStorage .getItem ('age' )) localStorage .removeItem ('age' ) </script > </body > </html >
sessionStorage(了解) 特性:
用法跟localStorage基本相同
区别是:当页面浏览器被关闭时,存储在 sessionStorage 的数据会被清除
存储:sessionStorage.setItem(key,value)
获取:sessionStorage.getItem(key)
删除:sessionStorage.removeItem(key)
localStorage 存储复杂数据类型 问题: 本地只能存储字符串,无法存储复杂数据类型.
解决: 需要将复杂数据类型转换成 JSON字符串,在存储到本地
语法: JSON.stringify(复杂数据类型)
JSON字符串:
首先是1个字符串
属性名使用双引号引起来,不能单引号
属性值如果是字符串型也必须双引号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <body > <script > const goods = { name : '小米' , price : 1999 } localStorage .setItem ('goods' , JSON .stringify (goods)) </script > </body >
问题: 因为本地存储里面取出来的是字符串,不是对象,无法直接使用
**解决: **把取出来的字符串转换为对象
语法: JSON.parse(JSON字符串)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <body > <script > const goods = { name : '小米' , price : 1999 } localStorage .setItem ('goods' , JSON .stringify (goods)) console .log (JSON .parse (localStorage .getItem ('goods' ))) </script > </body >
综合案例 数组map 方法 使用场景:
map 可以遍历数组处理数据,并且返回新的数组
语法:
1 2 3 4 5 6 7 8 9 10 11 12 <body> <script > const arr = ['red' , 'blue' , 'pink' ] const newArr = arr.map (function (ele, index ) { return ele + '颜色' }) console .log (newArr)</script > </body>
map 也称为映射。映射是个术语,指两个元素的集之间元素相互“对应”的关系。
map重点在于有返回值,forEach没有返回值(undefined)
数组join方法 作用: join() 方法用于把数组中的所有元素转换一个字符串
语法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <body > <script > const arr = ['red' , 'blue' , 'pink' ] const newArr = arr.map (function (ele, index ) { return ele + '颜色' }) console .log (newArr) console .log (newArr.join ()) console .log (newArr.join ('' )) console .log (newArr.join ('|' )) </script > </body >
Web APIs - 第6天笔记
目标:能够利用正则表达式完成小兔鲜注册页面的表单验证,具备常见的表单验证能力
正则表达式 正则表达式 (Regular Expression)是一种字符串匹配的模式(规则)
使用场景:
例如验证表单:手机号表单要求用户只能输入11位的数字 (匹配)
过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等
正则基本使用
定义规则
使用正则
test()方法
用来查看正则表达式与指定的字符串是否匹配
如果正则表达式与指定的字符串匹配 ,返回true
,否则false
1 2 3 4 5 6 7 8 9 10 11 12 <body > <script > const str = 'web前端开发' const reg = /web/ console .log (reg.test (str)) console .log (reg.test ('java开发' )) </script > </body >
元字符
普通字符:
大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。
普通字符只能够匹配字符串中与它们相同的字符。
比如,规定用户只能输入英文26个英文字母,普通字符的话 /[abcdefghijklmnopqrstuvwxyz]/
元字符(特殊字符)
是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。
比如,规定用户只能输入英文26个英文字母,换成元字符写法: /[a-z]/
边界符 正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符
如果 ^ 和 $ 在一起,表示必须是精确匹配
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 > <script > const reg = /^web/ console .log (reg.test ('web前端' )) console .log (reg.test ('前端web' )) console .log (reg.test ('前端web学习' )) console .log (reg.test ('we' )) const reg1 = /web$/ console .log (reg1.test ('web前端' )) console .log (reg1.test ('前端web' )) console .log (reg1.test ('前端web学习' )) console .log (reg1.test ('we' )) const reg2 = /^web$/ console .log (reg2.test ('web前端' )) console .log (reg2.test ('前端web' )) console .log (reg2.test ('前端web学习' )) console .log (reg2.test ('we' )) console .log (reg2.test ('web' )) console .log (reg2.test ('webweb' )) </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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 <body > <script > const reg1 = /^w*$/ console .log (reg1.test ('' )) console .log (reg1.test ('w' )) console .log (reg1.test ('ww' )) console .log ('-----------------------' ) const reg2 = /^w+$/ console .log (reg2.test ('' )) console .log (reg2.test ('w' )) console .log (reg2.test ('ww' )) console .log ('-----------------------' ) const reg3 = /^w?$/ console .log (reg3.test ('' )) console .log (reg3.test ('w' )) console .log (reg3.test ('ww' )) console .log ('-----------------------' ) const reg4 = /^w{3}$/ console .log (reg4.test ('' )) console .log (reg4.test ('w' )) console .log (reg4.test ('ww' )) console .log (reg4.test ('www' )) console .log (reg4.test ('wwww' )) console .log ('-----------------------' ) const reg5 = /^w{2,}$/ console .log (reg5.test ('' )) console .log (reg5.test ('w' )) console .log (reg5.test ('ww' )) console .log (reg5.test ('www' )) console .log ('-----------------------' ) const reg6 = /^w{2,4}$/ console .log (reg6.test ('w' )) console .log (reg6.test ('ww' )) console .log (reg6.test ('www' )) console .log (reg6.test ('wwww' )) console .log (reg6.test ('wwwww' )) </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 <body > <script > const reg1 = /^[abc]$/ console .log (reg1.test ('a' )) console .log (reg1.test ('b' )) console .log (reg1.test ('c' )) console .log (reg1.test ('d' )) console .log (reg1.test ('ab' )) const reg2 = /^[a-z]$/ console .log (reg2.test ('a' )) console .log (reg2.test ('p' )) console .log (reg2.test ('0' )) console .log (reg2.test ('A' )) const reg3 = /^[a-zA-Z0-9]$/ console .log (reg3.test ('B' )) console .log (reg3.test ('b' )) console .log (reg3.test (9 )) console .log (reg3.test (',' )) const reg4 = /^[a-zA-Z0-9_]{6,16}$/ console .log (reg4.test ('abcd1' )) console .log (reg4.test ('abcd12' )) console .log (reg4.test ('ABcd12' )) console .log (reg4.test ('ABcd12_' )) const reg5 = /^[^a-z]$/ console .log (reg5.test ('a' )) console .log (reg5.test ('A' )) console .log (reg5.test (8 )) </script > </body >
字符类 某些常见模式的简写方式,区分字母和数字
替换和修饰符 replace 替换方法,可以完成字符的替换
1 2 3 4 5 6 7 8 9 <body > <script > const str = '欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神' </script > </body >
修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等
i 是单词 ignore 的缩写,正则匹配时字母不区分大小写
g 是单词 global 的缩写,匹配所有满足正则表达式的结果
1 2 3 4 5 6 7 8 9 10 11 12 13 <body > <script > const str = '欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神' const strEnd = str.replace (/前端/g , 'web' ) console .log (strEnd) </script > </body >
正则插件
change 事件 给input注册 change 事件,值被修改并且失去焦点后触发
判断是否有类
元素.classList.contains() 看看有没有包含某个类,如果有则返回true,么有则返回false
个人实战文档 本次实战是对自己整个api阶段的总结。
参考效果如下地址:
http://erabbit.itheima.net/#/product/3995139
本次实战主要分为以下几个模块。
顶部导航模块
需求:
顶部导航开始不显示
等页面滑到主导航栏,这个新顶部导航栏滑动下拉显示 ,并且改为固定定位
等页面滑到上面,新顶部导航栏隐藏
图片切换模块
放大镜效果
业务分析:
①:鼠标经过对应小盒子,左侧中等盒子显示对应中等图片
②: 鼠标经过中盒子,右侧会显示放大镜效果的大盒子
③: 黑色遮罩盒子跟着鼠标来移动
④: 鼠标在中等盒子上移动,大盒子的图片跟着显示对应位置
思路分析:
①:鼠标经过小盒子,左侧中等盒子显示对应中等图片
获取对应的元素
采取事件委托的形式,监听鼠标经过小盒子里面的图片, 注意此时需要使用 mouseover
事件,因为需要事件冒泡触发small
让鼠标经过小图片的爸爸li盒子,添加类,其余的li移除类(注意先移除,后添加)
鼠标经过小图片,可以拿到小图片的src, 可以做两件事
让中等盒子的图片换成这个 这个小图片的src
让大盒子的背景图片,也换成这个小图片的 src (稍后做)
②: 鼠标经过中等盒子,右侧大盒子显示
用到鼠标经过和离开,鼠标经过中盒子,大盒子 利用 display 来显示和隐藏
鼠标离开不会立马消失,而是有200ms的延时,用户体验更好,所以尽量使用定时器做个延时 setTimeout
显示和隐藏也尽量定义一个函数,因为鼠标经过离开中等盒子,会显示隐藏,同时,鼠标经过大盒子,也会显示和隐藏
给大盒子里面的背景图片一个默认的第一张图片
③: 黑色遮罩盒子跟着鼠标来移动
先做鼠标经过 中等盒子,显示隐藏 黑色遮罩 的盒子
让黑色遮罩跟着鼠标来走, 需要用到鼠标移动事件 mousemove
让黑色盒子的移动的核心思想:不断把鼠标在中等盒子内的坐标给黑色遮罩层 let top 值,这样遮罩层就可以跟着移动了
1 2 3 4 5 6 7 8 let mx = 0 , my = 0 ;if (x <= 100 ) mx = 0 if (x > 100 && x < 300 ) mx = x - 100 if (x >= 300 ) mx = 200 if (y <= 100 ) my = 0 if (y > 100 && y < 300 ) my = y - 100 if (y >= 300 ) my = 200
大盒子图片移动的计算方法:
中等盒子是 400px 大盒子 是 800px 的图片
中等盒子移动1px, 大盒子就应该移动2px, 只不过是负值
1 2 large.style .backgroundPositionX = - 2 * mx + 'px' large.style .backgroundPositionY = - 2 * my + 'px'
放大镜完整代码:
其他模块 此模块可以根据自己时间添加
点击模块
tab栏切换模块
返回顶部模块 页面滚动底部,可以出现一个侧边栏,点击返回顶部,可以返回顶部