文章目录
第一章: JavaScript 简介与语法
JavaScript 是什么
- javaScript属于高级编程语言,是运行在客户端(自己的电脑)的脚本语言。Java是编译性语言(编译好了再执行), js是解释性语言(边编译边执行)。
- 作用: 表单动态校验 网页特效 服务端开发等
- 浏览器执行JS简介:浏览器分为两部分,渲染引擎和JS引擎。渲染引擎,用来解析HTML与CSS,俗称内核,比如Chrome浏览器的blink, 老版本的webkit; JS引擎,也称为JS解释器,用来读取网页中的JavaScript代码,对其处理后运行,比如chrome浏览器的V8.
- 浏览器本身并不会执行JS代码,而是通过内置JavaScript引擎(解释器)来执行JS代码。JS引擎执行代码时逐行解释每一句源码(转换为机器语言) ,然后由计算机去执行,所以JavaScript语言归为脚本语言,会逐行解释执行。
- JavaScript 组成: ECMAScript语法、DOM(文档对象模型)、BOM(浏览器对象模型)
- js写法: 行内式、内嵌式、外部JS文件
<script src="my.js"></script>
- 注释
// 1.单行注释 ctrl + /
/* 2.多行注释 默认 shift + alt + a 在vscode中修改多行注释的快捷键: crtl + shift + /
- JavaScript 输入输出语句
方法 | 说明 | 归属 |
---|---|---|
alert(msg) | 浏览器弹出警示框 | 浏览器 |
console.log(msg) | 浏览器控制台打印输出信息 | 浏览器 (log是日志的意思) |
prompt(info) | 浏览器弹出输入框,用户可以输入 |
变量
- 为什么需要变量: 因为我们一些数据需要保持,所以需要保存
- 本质:是程序在内存中申请的一个用来存放数据的空间
- 变量初始化: 声明一个变量并赋值
var myname = 'plink';
console.log(myname)
- 变量如何使用: 我们使用变量的时候,一定要先声明,然后再赋值。
- 同时声明多个变量:只需要写一个var, 多个变量名之间使用英文逗号隔开。变量不声明,直接赋值,也可以使用。
// 声明多个变量
var age = 10, name = 'zd', sex = 2;
var age = 10,
address = '火影村',
gz = 2000;
// 声明不赋值,是undefined; 不声明不赋值,报错。
// 赋值不声明
qq = 10;
console.log(qq);
- 变量命名:字母,下划线
- 临时变量的写法(就是未赋值的变量,不会报错)
var temp;
- 学会交换2个变量
数据类型
- 为什么需要数据类型: 在计算机中,不同的数据所占用的存储空间不同,为了方便把数据分成所需内存大小不同的数据,充分利用存储空间,于是定义了不同的数据类型。
- 变量的数据类型: js 数据一种弱类型的或者动态语言,变量只有在程序运行时js引擎根据赋的值(等号右边变量值)的数据类型来判断,运行完毕之后,变量就确定了数据类型。
- 数据类型分类:
简单数据类型 | 说明 | 默认值 |
---|---|---|
数字型Number | isNaN(12)判断是否为数字型 | |
字符串型 String | var strMyname = ‘唐老鸭’; 单引号和双引号都可以,推荐JS用单引号 | 字符串中需要引号,可“外双内单,外单内单”;换行等用转义符。 |
- 转义符:转义符都是 \ 开头的,注意是方向。 常用转义符如下
转义符 | 解释说明 |
---|---|
\n | 换行符,n是newline的意思 |
\ | 斜杆\ |
’ | '单引号 |
" | "双引号 |
\t | tab 缩进 |
\b | 空格,b 是blank的意思 |
- 检测字符串长度:alert(str.length)
- 字符串拼接: 多个字符串之间可以使用 + 进行拼接,其拼接方式为字符串 + 任何类型 = 拼接之后的新字符串
拼接前会把与字符串相加的任何类型转换为字符串,再拼接成一个新的字符串。
alert('12' + 12); //1212
alert('hello' + ' ' + 'word'); //hello word
- 拼接加强, 变量与字符串拼接
console.log('pink' + 18 + '岁';
var age = 18;
console.log('pink老师' +age +'岁'; //变量不需要加引号
- 交互程序编程
- 布尔型Boolean
布尔型有两个数值: true (真,对)和false(假,错)
布尔型和数字型相加的时候,true的值为1, false为0 - Undefined 和 Null
一个声明没有被赋值的变量,会有一个默认值,undefined
var variable;
console.log(variable); //undefined
console.log('你好' + variable); //你好undefined
console.log(11 + variable); // NaN
console.log(ture + variable); //NaN
一个声明变量给Null,里面的值为空
var vari = null;
console.log('你好'+ vari); //你好null
consloe.log(11+ null ); //11
console.log(true +vari); //1
- 获取变量数据类型 typeof
var num = 10;
console.log(typeof num); //number
数据类型转换
- 转换为字符串
方式 | 说明 | 案例 |
---|---|---|
变量.toString() | 数字转字符串 | var num =1; alert(num.toString()); |
String()强制转换 | 转成字符串 | var num=1; alert(String(num)); |
加号拼接字符串 / 隐式转换 | 和字符串拼接的结果都是字符串 | vatr num=1;alert(num+‘我是字符串’)) |
- 转换为数字型
方式 | 说明 | 案例 |
---|---|---|
parseInt(string)函数 | 将string类型转换为整数数值型 | parselnt(‘120px’); //120; parseInt(rem120px); //NaN |
parseFloat(string)函数 | 将string类型转成浮点数数值型 | parseFloat(‘78.5’) |
Number()强制转换函数 | 将string类型转换为数值型 | Number(‘12’); //12 |
js隐式转换(- * /) | 利用算数运算隐式转换为数值型 | ‘12’ - 0 ; //12; console.log(‘123’ - ‘122’); //1 |
加法器案例: 计算两个数的值,用户输入第一个值后,继续弹出第二个输入框并输入第二个值,最后弹出一个输出窗口显示两次输入值相加的结果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
//先弹出一个对话框,输入第一个值,保存起来;
//弹出第二个对话框,输入第二个值,保存起来;
//将两个值进行计算,保存起来;
//弹出第三个对话框,输出计算结果;
var num1 = prompt('请输入第一个值'); //为字符串型
var num2 = prompt('请输入第二个值');
var result = parseFloat(num1) + parseFloat(num2);
alert('计算结果为:'+ result);
</script>
</head>
<body>
</body>
</html>
- 转换为布尔型
方式 | 说明 | 案例 |
---|---|---|
Boolean()函数 | 其他类型转成布尔值 | Boolean(‘true’); |
代表空、否定的值会被转换为false, 如’ '、0、NaN、undefind | ||
其余的值都会被转换为true |
-
标识符、关键字、保留字
标识(zhi)符:就是指开发人员为变量、属性、函数、参数取的名字。
标识符不能是关键字或保留字。关键字: js本身已经使用的字,不能再用他们来充当变量名、方法名。包括:break、case、catch、continue、with等。
保留字:实际上就是预留的’关键字’,意思是虽然现在还不是关键字,但是未来可能会成为关键字,同样不能使用它们来当变量名或方法名。包括:boolean, byte, class, const,double, enum, export, extends,float.
-
作业
- 给同桌讲讲交换两个变量的算法(不管他愿不愿意听)
- 依次询问并获取用户的姓名、年龄、性别,并打印用户信息。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
//先弹出第一个对话框,提示输入姓名,并保存
//弹出第二个对话框,提示输入年龄,并保存
//弹出第三个对话框,提示输入性别,并保存
//将姓名、年龄、性别信息连起来,用换行符隔开\n,并保存
//弹出第四个窗口,显示用户信息
var name = prompt('请输入你的姓名');
var age = prompt('请输入你的年龄');
var sex = prompt('请输入你的性别');
alert('您的姓名是:' + name + '\n' + '您的年龄是:' + age + '\n'+ '您的性别是:' + sex);
</script>
</head>
<body>
</body>
</html>
数值运算
- 表达式和返回值
由数字、运算符、变量等组成的式子 我们称为 **表达式 ** 1+1
console.log(1+1); // 2 就是返回值
// 1+1 = 2
// 在我们程序里面 2 = 1+1 把我们的右边表达式计算完毕把返回值给左边
var num = 1+1
- 递增和递减运算符概述
如果需要反复给数字变量添加或减去1,可以使用递增(+ +)和递减(- -)运算符来完成
在JavaScript中, 递增(+ +)和递减(- -)既可以放在变量前面,也可以放在变量后面。放在变量前面时,我们可以称为,前置递增(+ +)运算符,放在变量后面时,我们可以称为后置递减(- -)运算符。
// 前置递增运算符 ++写在变量的前面
// 先自加,后返回值
var age = 10;
++age ; //类似于 age = age +1
console.log(++age + 10);
// 后置(- -)运算符
var num = 10;
num ++ ; // num = num + 1 先返回值, num++ = 10, 后自加,num=11
// 1. 前置自增和后置自增如果单独使用,效果是一样的
// 2. 后置自增 口诀: 先返回原值 后子加1
var age = 10;
console.log(age ++ + 10); // 11
console.log(age++ + ++age) // age++ = 10, age = 11; ++age = 11+1 = 12 ; console.log(..) 结果为, 10 +12 = 22
考点:前置自增与后置自增的区别?
- 比较运算符
概念: 比较运算符(关系运算符)是两个数据进行比较时所使用的运算符,比较运算后,会返回一个布尔值(true/false) 作为比较运算的结果。
符号 | 作用 | 用法 |
---|---|---|
= | 赋值 | 把右边给左边 |
== | 判断 | 判断两边是否相等(注意此时有隐式转换,会把字符串转换为数值型) |
=== | 全等 | 判断两边的值和数据类型是否完全相同 |
- 逻辑运算符
概念:逻辑运算符用来进行布尔值的运算符,其返回值也是布尔值。后面开发中经常用于多个条件的判断
逻辑运算符 | 说明 | 案例 |
---|---|---|
&& | “逻辑与”,简称"与" and | true && false |
11 | “逻辑或”, 简称"或" or | true 11false |
! | 逻辑"非" not | !true //(false) 逻辑fei(!)也叫作取反符,用来取一个布尔值相反的值,如true的相反值是false, isOK是false |
- 短路运算(逻辑中断) (考点)
短路运算的原理:当有多个表达式(值)时,左边的表达式值可以确定结果时,就不再继续运算右边的表达式的值;
1. 逻辑与
语法: 表达式1 && 表达式2
如果第一个表达式的值为真,则返回表达式2 (除0以外,所有的值都是真的)
如果第一个表达式的值为假,则返回表达式1
console.log(233 && 444); // 444
console.log(0 && 222); // 222
2 逻辑或 短路运算
语法: 表达式1 || 表达式2
如果第一个表达式的值为真,则返回表达式1
如果第一个表达式的值为假,则返回表达式2
console.log( 123 || 456); //123
console.log(0 || 456); // 456
console.log(123 || 456 || 789); //123
- 赋值运算符
概念:用来把数据赋值给变量的运算符。
赋值运算符 | 说明 | 案例 |
---|---|---|
= | 直接赋值 | var usrName = ‘我是值’; |
+=、-= | 加、减一个数后再赋值 | var age = 10; age+ = 5; //15 |
*=、/=、%= | 乘、除、取余后再赋值 |
- 运算符的优先级
优先级 | 运算符 | 顺序 |
---|---|---|
1 | 小括号 | () |
2 | 一元运算符 | ++ - ! |
3 | 算数运算符 | 先 * / % 后 + - |
4 | 关系运算符 | > >= < <= |
5 | 相等运算符 | == != === !== |
6 | 逻辑运算符 | 先&& 后II |
7 | 赋值运算符 | = |
8 | 逗号运算符 | , |
流程控制
流程控制主要有三种结构: 顺序结构、分支结构和循环结构
分支语句
if 语句
switch语句
var age = prompt('请输入你的年龄:');
if(age >= 18) {
alert('我想带你去网吧偷耳机');
};
if(age >= 18) {
alert('我想带你去网吧偷耳机');
} else{
alert('回家做作业')
};
判闰年案例分析:
算法:能被4整除且不能整除100的为闰年或者能够被400整除的也是闰年。
<script>
var year = prompt('请输入您的年份:');
if (year % 4 == 0 && year % 100 !=0 || year % 400 ==0){
alert('你输入的年份是闰年!');
} else{
alert('你输入的年份不是闰年!');
}
</script>
- if else if 多分支语句
if(条件表达式1){
//语句1;
}else if(条件表达式2){
//语句2;
}else if(条件表达式3){
//语句3;
}else{
//语句4;
}
- 三元表达式 代替 if else 语句 (经常使用)
概念: 有三元运算符组成的式子我们称为三元表达式
语法结构: 条件表达式 ?表达式1:表达式2
执行思路:如果条件表达式的结果为真,则 返回 表达式1 的值, 如果条件表达式结果为假,则 返回 表达式2 的值
var num = 10;
var result = num >5 ? '是的': '不是的';
console.log(result);
计时器中数字补0 案例:如果用户输入的数字小于10, 则在数字前面补一个0,大于10,则不用补0
var time = prompt('请输入一个0~59之间的数字');
var result = time < 10 ? '0' + time : time;
alert(result);
- switch多分支语句,实现多选1
语法结构:switch语句用于基于不同的条件执行不同的代码,当针对变量设置一系列的特定值的选项时,就可以使用switch。
switch(表达式){
case value1:
执行语句1;
break;
case value2;
执行语句2;
break;
....
default:
执行最后的语句:
}
执行思路: 利用我们的 表达式的值,和 case 后面的选项值相匹配 ,如果匹配上,就执行case里面的语句, 如果都没有匹配上,那么执行 default里面的语句。
注意事项:
1: 开发中,表达式经常写成变量
2: 表达式里的值 和 case 里面的值相匹配时 是 全等 必须是值和数据类型一致 才可以 num == 3
3: break 如果当前case里面没有 break, 则不会退出 switch 是继续执行下一个 case
案例: 查询水果
用户在弹出框里面输入一个水果,如果有就弹出该水果的价格,如果没有该水果就弹出‘没有此水果’
var fruit = prompt('请输入一个水果的名称');
switch(fruit){
case 'apple':
alert('4元一斤');
break;
case '榴莲':
alert('35元一斤');
break;
default:
alert('没有此水果');
}
- ** switch 语句 和 if else if语句的区别**
① 一般情况下,他们两个语句可以相互替换
② switch…case 语句通常处理case 为比较确定值的情况,而 if…else …语句更加灵活,通常用于范围判断大于、等于某个范围
③switch 语句进行条件判断后直接执行到程序的条件语句,效率更高。而 if…else语句有几种条件,就得判断多少次。
④当分支比较少时,if…else语句的执行效率比switch语句高
⑤当分支比较多时,switch语句的执行效率比较高,而且结构更清晰
循环
循环的目的:可以反复的执行某些代码
JS 中的循环
- for 循环
for(初始化变量;条件表达式;操作表达式){
// 循环体
}
初始化变量: 就是用var 声明的 一个普通变量, 通常用于作为计数器使用
条件表达式:就是用来决定每一次循环是否继续执行 就是终止的条件
操作表达式 是每次循环最后执行的代码 经常用于我们计数器变量进行更新(递增或递减)
- for 循环的执行过程
(第一种: 将需要存储数据的变量先声明,数值一定为0)
<script>
for(var i=1; i<=100; i++){
console.log('你好嘛')
}
</script>
案例:求1~ 100之间的整数累加和
<script>
//求1~100之间所有数的平均值
//算法 平均数=总和/个数 我们需要一个平均值 所有数的和 sum的变量
//我们需要一个存储结果的变量sum 和 average, 但是初始值一定是0
var sum = 0;
var average = 0;
for(var i=1; i<=100;i++){
sum += i;
}
average = sum/100;
console.log(average);
// 求1~100之间所有偶数的和奇数的和
//算法 偶数的和 = 偶数相加 奇数的和等于奇数相加 需要偶数和的变量 奇数和的变量
var even = 0;
var odd = 0;
for(var i = 1; i<=100; i++){
if(i % 2 == 0){
even += i;
}else{
odd += i;
}
}
console.log('1~100之间所有偶数的和为'+osum);
console.log('1~100之间所有奇数的和为'+jsum);
</script>
案例: 计算学生成绩(重点:prompt取出的值是字符串数据)
var num = prompt('请输入学生人数');
var sum = 0;
var average =0;
for(var i = 1; i<= num; i++){
var grade = prompt('请输入第' + i +'学生的成绩');
//prompt 取出的数据是字符串型的
sum += parseFloat(grade); //转换为数字型
}
average = sum/num;
alert('所有学生的平均成绩为:'+ average);
第二种 追加字符串的方式声明变量 var str = ’ ';
案例:一行打印5颗星星
var str = '';
for(var i = 1; i<=5;i++){
str = str + '☆';
}
alert(str);
- 双重 for 循环
很多情况下,单层for循环并不能满足我们的需求,比如要打印5行5列的图形、打印一个倒直三角形等,此时就可以通话循环嵌套来实现。
循环嵌套 是指在一个循环语句中再定义一个循环语句的语法结构,例如在for循环语句中,可以再嵌套一个for 循环,这样的for 循环语句我们称之为 双重for 循环
//打印5行星星
var str = '';
for(var i=1; i<=5;i++) {
for(var j = 1; j<= 5; j++){
str = str + '☆';
}
str = str +'\n'; //换行
}
alert(str)
案例:打印九九乘法表
var str = '';
for(var i = 1; i<=9; i++){
for(var j = 1; j <= i; j++){
str += j + 'x' + i + '=' + i*j + '\t'; //变量不加引号
}
str += '\n';
}
console.log(str);
while循环
语法结构: while 当…的时
var ‘变量’ = '变量值'; //while循环里面应该也有计数器 初始化变量
while(条件表达式){
//循环体
// 操作表达式 //里面应该也有操作表达式 完成计数器的更新 防止死循环
}
执行思路:
①先执行条件表达式,如果结果为true, 则执行循环体代码;如果为false,则退出循环,执行后面代码;
②执行循环体代码
③循环体代码执行完毕后,程序会继续判断执行条件表达式,如果条件仍为true, 则会继续执行循环体,直到循环体条件为false时,整个循环过程才会结束。
当条件表达式结果为true时 则执行循环体 否则 退出循环
判断条件比较复杂时,我们使用while循环。
案例分析:
var message = prompt('你爱我吗');
while(message !== '我爱你'){
message = prompt('你爱我吗');
} // !== 对应 ===, 不相等 和相等,===表示值和数据类型完全一致时为true,数据类型可以为字符串; != 对应 ==,是数值相等运算符
alert('我也爱你!');
do while 循环
do while 和 while 的区别,do while至少执行了一次循环体
语法结构:
var '变量' = ‘变量值’; //计数器 初始化变量
do{
// 循环体
}while(条件表达式)
// 执行思路 跟while不同的地方在于 do while先执行一次循环体 再判断条件 如果条件表达式结果为真,则继续执行循环体,否则退出循环
//案例 打印人的一生
var i = 1;
do{
console.log('这个人今年' + i + '岁了');
i ++;
}while(i <= 100)
//打印我爱你
var message = prompt('你爱我吗');
do{
message = prompt('你爱我吗')
}while(message !== '我爱你');
alert('我也爱你')
// 计算0~100之间数字的累加和
var sum = 0;
var i = 0;
do{
sum += i;
i++;
}while(i <= 100)
console.log(sum);
- 循环小结
①js中有 for、while、 do while 循环
② 三个循环很多情况下都可以互相替代
③如果是用来计次数,跟数字相关,三种使用基本相同,但是我们更喜欢用for
④while 和do…while 可以做更复杂的条件判断,比for 循环灵活一些
⑤ while 和 do… while 执行顺序不一样,while 先判断后执行, do…while先执行一次,再判断执行
⑥while 和do…while执行次数不一样,do…while至少会执行一次循环体, 而while 可能一次也不执行
⑦实际工作中,我们更常用for循环,它写法更简洁直管,重点学习。
作业:简易的ATM
//for 循环
var money = 100;
for (var i = 1; i <= 4; i++){
var message = prompt('请输入您要的操作:'+ '\n' + '1.存钱' + '\n' + '2.取钱' + '\n'+ '3.显示余额' + '\n' + '4.退出');
message = parseFloat(message);
if (message == 1){
var cunqian = prompt('请输入存的钱数:');
var result= money + parseFloat(cunqian);
money = result;
alert('您的余额为' + result + '元');
}
else if (message == 2){
var cunqian = prompt('请输入取的钱数:');
var result= money - parseFloat(cunqian);
money = result;
alert('您的余额为' + result + '元');
}
else if (message == 3){
alert('您的余额为' + money + '元');
}
else if (message == 4){
break;
}
}
//while 循环
var money = 100;
a=true;
while (a == true){
var message = prompt('请输入您要的操作:'+ '\n' + '1.存钱' + '\n' + '2.取钱' + '\n'+ '3.显示余额' + '\n' + '4.退出');
message = parseFloat(message);
if (message == 1){
var cunqian = prompt('请输入存的钱数:');
var result= money + parseFloat(cunqian);
money = result;
alert('您的余额为' + result + '元');
}
else if (message == 2){
var cunqian = prompt('请输入取的钱数:');
var result= money - parseFloat(cunqian);
money = result;
alert('您的余额为' + result + '元');
}
else if (message == 3){
alert('您的余额为' + money + '元');
}
else if (message == 4){
a = false;
}
}
continue和 break 关键字
数组
数组新增元素
- 通过修改length 长度
- 通过修改数组索引新增数组元素
<script>
//1. 新增数组元素 修改length长度
var arr = ['red','green','blue'];
arr.length = 5; // 我们把数组的长度修改为5 里面应该有5个元素
console.log(arr);
console.log(arr[3]); // undefined
console.log(arr[4]); // undefined
//2. 新增元素 修改索引引号 追加数组元素
var arr1 = ['red', 'green','blue'];
arr1[3] = 'pink';
arr1[4] = 'hotpink';
console.log(arr1);
arr1[0] = 'yellow'; //这里是替换原来的数组元素
arr1 = '有点意思'; //不要直接给 数组名赋值 否则里面的数组元素都没有了
</script>
- 案例1:数组新增元素 新建一个数组,里面存放10个整数(1~10)
//1. 核心原理 使用for 循环来追加数组
//2. 声明一个空数组 arr
//3.循环中的计数器 i 可以作为数组元素存入
//4. 由于数组的索引号是从0 开始的,因此计数器从0 开始更合适,存入的数组元素要 +1
var arr = [];
for(var i = 0; i < 10; i++){
arr[i] = i + 1; //不能直接给arr 赋值
}
console.log(arr);
- 案例2: 筛选数组
//要求: 将数组[2,0,6,1,77,0,52,0,25,7]中大于等于10的元素选出来,放入新数组
//① 声明一个新的数组用于存放新数据 newArr
//② 遍历原来的旧数组,找出大于等于10的元素。
//③ 依次追加给新数组 newArr
//第一种方法:
var arr = [2,0,6,1,77,0,52,0,25,7];
var newArr = [];
var j = 0; // 运用一个新变量,要写在外面,若写在for 循环里,每次都会被赋值为0
for (var i = 0; i < arr.length; i++){
if(arr[i] >= 10){
newArr[j] = arr[i];
j++;
}
}
console.log(newArr);
//第二种方法: 利用arr.length 自动检测数组长度
var arr = [2,0,6,1,77,0,52,0,25,7];
var newArr = []; // 此时, newArr.length = 0, length自动检测数组长度
//var j = 0; // 运用一个新变量,要写在外面,若写在for 循环里,每次都会被赋值为0
for (var i = 0; i < arr.length; i++){
if(arr[i] >= 10){
newArr[newArr.length] = arr[i];
j++;
}
}
console.log(newArr);
冒泡排序
冒泡排序: 是一种简单的排序算法。它重复地走访要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换。也就是说该数列已经排序完成。
<script>
var arr = [5,4,3,2,1];
for (var i = 0; i < arr.length-1; i++){
for (var j = 0; j < arr.length - i -1; j++){
if(arr[j] > arr[j+1]){
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
console.log(arr); //[1, 2, 3, 4, 5]
</script>
函数
概念: 就是封装了一段可以被重复执行调用的代码块
目的:让大量代码重复使用
函数使用
- 声明函数
function是声明函数的关键字,必须小写
由于函数一般是为了实现某个功能才定义的,所以通常我们将函数名命名为动词。
//声明函数
function 函数名(){
// 函数体}
- 调用函数
//调用函数
函数名(); // 通过调用函数名来执行函数体代码
调用函数的时候千万不能忘记添加小括号
口诀:函数不调用,自己不执行
- 函数的参数(形参和实参)
function 函数名(形参1,形参2...){//在声明函数调用的小括号里面 是形参
}
函数名(实参1,实参2...); // 在函数调用的小括号里面是实参 调用的时候 实参传递给形参
//函数的参数可以有,也可以没有
//多个参数之间,用逗号隔开
// 形参可以看做是不用声明的变量
- 函数形参和实参个数不匹配问题
参数个数 | 说明 |
---|---|
实参个数等于形参个数 | 输出正确结果 |
实参个数多于形参个数 | 只取到形参的个数 |
实参个数小于形参个数 | 多的形参定义为Undefined,结果为NaN |
function sum(num1,num2){
console.log(num1 + num2)}
sum(100, 200); //实参个数等于形参个数, 输出正确结果
sum(100,200,400); //实参个数多于形参个数,只取到形参的个数
sum(100); //实参个数小于形参个数,多的形参定义为Undefined,结果为NaN
- 函数的返回值 return
将函数的结果返回给函数调用者
return的作用
(1)将函数结果传递给调用者
(2)return终止函数, return后面的代码不会被执行
(3)return只能返回一个结果,当返回多个结果,返回的结果是最后一个值
(4)如果想要输出多个值,可以利用数组,对象来输出
(5)函数如果没有 return , 返回 undefined
- 案例:求最大值
<script>
//案例1:利用函数 求任意两个数的最大值
function getMax(num1, num2){
if(num1 > num2){
return num1;
}
else{
return num2;
}
return num1 > num2 ? num1:num2;
}
result = getMax(1, 3);
console.log(result);
//案例2: 利用函数求数组中的最大值
function getArrMax(arr){
var max = arr[0];
for(var i = 0; i < arr.length; i++){
if(arr[i] > max){
max = arr[i];
//等号=表示赋值运算符,例如E1=E2,表示将E2的值存放到变量E1中,E1必须是可修改的左值,也就是变量.
//双等号==是逻辑判断运算符,表示相等,例如E1E2,表示判断E1和E2的值是否相等,如果相等返回1,不相等返回0值。
}
}
return max;
}
//在我们实际开发里面,我们经常使用一个变量来接受 函数的返回结果 使用更简单
var arr1 = getArrMax([2, 3, 6, 18, 45]);
console.log(arr1);
</script>
- arguments 的使用
只有函数才有 arguments 对象 而且是每个函数都内置好了这个arguments
作用: 里面存储了所有传递过来的实参
是伪数组 并不是真正意义上的数组
具有数组的 length 属性
按照索引的方式进行存储
它没有真正数组的一些方法 pop() push() 等
function fn(){
// console.log(arguments) ; 里面存储了所有传递过来的实参
// console.log(arguments.length);
// console.log(arguments[2];
// 我们可以按照数组的方式遍历 arguments
for (var i = 0; i < arguments.length; i++){
console.log(arguments[i]);
}
}
fn(1,2,3);
fn(1,2,3,4,5);
- 案例分析
<script>
//案例1:利用函数求任意个数的最大值
function getMax(){
var max = arguments[0];
for (var i = 0; i < arguments.length; i++){
if (arguments[i] > max){
max = arguments[i];
}
}
return max;
}
console.log(getMax(1,2,3));
console.log(getMax(1,2,3,44,5,77));
//案例2: 利用函数翻转任意数组
function reverse(){
var newArr = [];
for (var i = arguments.length -1; i >=0; i--){
newArr[newArr.length] = arguments[i]
}
return newArr;
}
console.log(reverse(1,2,3));
console.log(reverse(1,2,3,44,5,77));
//案例3: 利用函数对任意数组进行冒泡排序 sort
function sort(arr){
for(var i = 0; i < arr.length - 1; i++){
for(var j = 0; j < arr.length - i - 1; j++){
if(arr[j] > arr [j+1]){
var tempt = arr[j] ;
arr[j] = arr[j+1];
arr[j+1] = tempt;
}
}
}
return arr;
}
var arr1 = sort([1, 4,2,9]);
console.log(arr1);
var arr2 = sort([11, 7, 22, 999])
console.log(arr2);
//案例4: 判断闰年 输入一个年份,判断是否为闰年(闰年: 能被4整除并且不能被100整除,或者能被400整除)
function isRunyear(year){
var flag = false;
if(year % 4 == 0 && year % 100 !=0 || year % 400 == 0){
flag = true;
}
return flag;
}
console.log(isRunyear(2000));
console.log(isRunyear(2013));
</script>
函数可以调用另一个函数
function fn1(){
console.log(11);
fn2(); // 在fn1 函数里面调用了 fn2 函数
}
fn1()
function fn2(){
console.log(22);
}
// 案例: 用户输入年份,输出当前年份2月份的天数
function backDay(){
var year = prompt('请你输入年份:')
if (isRunyear(year)){
alert('您输入的年份是闰年,2月份有29天。')
}else{
alert('您输入的年份是平年,2月份有28天。')
}
}
backDay();
//判断是否为闰年函数
function isRunyear(year){
var flag = false;
if(year % 4 == 0 && year % 100 !=0 || year % 400 == 0){
flag = true;
}
return flag;
}
- 2种函数声明方式
<script>
//函数的2种声明方式
// 1.利用函数关键字自定义函数(命名函数)
function fn(){
}
fn(); //fn 是函数名
//2.函数表达式(匿名函数)
// var 变量名 = function(){};
var fun = function(aru){
console.log('我是函数表达式');
console.log(aru);
}
fun('pink老师');
//(1)fun是变量名 不是函数名
//(2)函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值 而函数表达式里面存的是函数
//(3)函数表达式也可以进行传递参数
</script>
JavaScript作用域
- JavaScript 作用域: 就是代码(变量)在某个范围内起作用和效果
- 目的: 为了提高程序的可靠性,更重要的是减少命名冲突
- js 的作用域(es6)之前: 全局作用域 局部作用域
- 全局作用域:整个script 标签 或者是在一个单独的js文件
<script>
var num = 10;
</script>
- 局部作用域(函数作用域)在函数内部就是局部作用域 这个代码的名字只在函数内部起效果和作用
function fn(){
var num = 20;
console.log(num);
}
fn();
全局变量和局部变量
全局变量: 根据作用域的不同,变量分为全局变量和局部变量
在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)
- 全局变量在代码的任何位置都可以使用
- 在全局作用域下 var 声明的变量 是全局变量
- 特殊情况下, 在函数内不适用 var 声明的变量也是全局变量(不建议使用)
在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)
- 局部变量只能在该函数内部使用
- 在函数内部 var 声明的变量是局部变量
- 函数的形参实际上就是局部变量
全局变量和局部变量的区别
- 全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存
- 局部变量: 只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就被销毁,因此更节省内存空间。
js在es6 的时候新增的块级作用域。
作用域链
作用域链: 内部函数访问外部函数的变量,采用的是链式查找的方式来决定取哪个值 这种结构我们称为作用域链 就近原则
<script>
//案例1: 结果是几
function f1(){
var num = 123;
function f2(){
var num = 0;
console.log(num); //站在目标出发,一层一层的往外查找 这里的num 取值 为 0
}
}
</script>
预解析
JS的运行机制
js代码是由浏览器中的js解析器来执行的。js解析器在运行js代码的时候分为两步:预解析和代码执行
预解析: js引擎会把js 里面所有的 Var 还有 function 提升到当前作用域的最前面。
代码执行: 按照代码书写的顺序从上往下执行
预解析分为 变量预解析(变量提升) 和 函数预解析(函数提升)
(1)变量提升: 就是把所有的变量声明提升到当前的作用域最前面 不提升赋值操作。
console.log(num); //undefined 坑1
var num = 10;
//相当于
// var num;
// console.LOG(num);
// num = 10;
fun(); //报错 坑2
var fun = function(){
console.log(22);
}
//函数表达式 调用必须写在函数表达式的下面
//相当于
// var fun;
// fun(); //这里fun没有被赋值为一个函数,调用会报错
// fun = function(){
// console.log(22);
// };
(2)函数提升 就是把所有的函数声明提升到当前作用域的最前面 不调用函数
fn(); //正确
function fn(){
console.log(22);
}
//相当于
function fn(){
console.log(22);
} //函数提升
fn();
function fn(){
console.log(22);
}
案例:结果是几 面试题
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;
// 相当于 var a = 9; b = 9; c = 9; 这里的 b 和 c 直接赋值 没有var 声明 当全局变量看
// 集体声明 var a = 9, b = 9, c = 9;
console.log(a);
console.log(b);
console.log(c);
}
f1();
console.log(a); // not defined a 是局部变量
console.log(b); // 9 b 是全局变量
console.log(c); //9 c 是全局变量
对象
对象: 在js中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串,数组,数组,函数等。
对象是由属性和方法组成的。
属性: 事物的特征,在对象中用属性来表示(常用名词)
方法: 事物的行为,在对象中用方法来表示(常用动词)
创建对象的三种方式
对象字面量: 就是花括号{ } 里面包含了表达这个具体事物(对象)的属性和方法。
{}里面采取键值对的形式表示
键: 相当于属性名
值:相当于属性值,可以是任意类型的值(数字类型,字符串类型,布尔类型,函数类型)
<script>
// 创建一个对象
var obj = {
uname:'张三疯',
age: 18,
sex: '男',
sayHi: function(){
console.log('hi~');
}
}
//(1) 里面的属性或方法我们采取键值对的形式 键 属性名: 值 属性值
// (2) 多个属性或者方法中间用逗号隔开的
// (3) 方法冒号后面跟的是一个匿名函数
//2.使用对象 对象调用
//(1)调用对象的属性 我们采取 对象名.属性名
console.log(obj.uname);
//(2)调用属性还有一种方法 对象名['属性名'],注意方括号里面的属性必须加引号
console.log(obj['age']);
//(3)调用对象的方法 sayHi 对象名.方法名(),注意这个方法名字后面一定加括号
obj.sayHi();
</script>
调用对象
(1)调用对象的属性 我们采取 对象名.属性名
(2)调用属性还有一种方法 对象名[‘属性名’], 注意方 括号里面的属性必须加引号
(3)调用对象的方法 sayHi 对象名.方法名(),注意这个方法名字后面一定加括号
变量、属性、函数、方法的区别
变量和属性的相同点:他们都是用来存储数据的
变量: 单独声明并赋值 使用的时候直接写变量名 单独存在
属性: 在对象里面不需要声明的 使用的时候必须是 对象属性
2. 函数和方法的相同点: 都是实现某种功能 做某件事
函数: 是单独声明 并且调用的 函数名() 单独存在的
方法: 在对象里面 调用的时候 对象,方法()
利用 new Object 创建对象
<script>
//利用 new Object 创建对象
var obj = new Object(); //创建了一个空的对象
obj.uname = '张山疯';
obj.age = 18;
obj.sex = '男';
obj.sayHi = function(){
console.log('hi~');
}
//(1)我们是利用 等号 = 赋值的方法 添加对象的属性和方法
//(2)每个属性和方法之间用 分号结束
console.log(obj.uname);
console.log(obj['sex']);
</script>
利用构造函数创建对象
为什么需要使用构造函数?
因为我们前面两种创建对象的方式一次只能创建一个对象
因为我们一次创建一个对象,里面很多的属性和方法大量相同的 我们只能复制
因此我们可以利用函数的方法 重复这些相同的代码 我们就把这个函数称为构造函数
又因为这个函数不一样,里面封装的不是普通代码,而是对象
构造函数 就是把我们对象里面一些相同的属性和方法抽象出来封装到函数里面
利用构造函数创建对象
function Star(uname,age, sex){
this.uname =uname;
this.age = age;
this.sex = sex;
this.sing = function(sang){
console.log(sang);
}
}
var dh = new Star('刘德华', 18,'男'); //利用构造函数生成一个对象,返回的结果是个对象
console.log(typeof dh);
//1. 构造函数名字首字母要大写
//2. 构造函数不需要return 就可以返回结果
//3. 调用构造函数必须使用 new
//4. 我们只要 new 构造函数名(); 一次就创建了一个对象
//5. 我们的属性和方法前面必须添加 this
console.log(dh.uname);
console.log(dh.age);
dh.sing('冰雨');
构造函数是泛指的某一大类
对象是特指的某一个
利用构造函数创建对象的过程称为对象实例化
new 关键字执行过程
- new 构造函数可以在内存中创建一个空的对象
- this 就会指向刚才创建的空对象
- 执行构造函数里面的代码 给这个空对象添加属性和方法
- 返回这个新对象(所以构造函数里面不需要return)
遍历对象
<script>
var obj = {
name: 'pink老师',
age: 18,
sex: '男',
fn: function(){}
}
// for in 遍历我们的对象
// for(变量 in 对象){
// }
for (var k in obj){
console.log(k); // k 变量 输出 得到的是 属性名
console.log(obj[k]); // obj[k] 得到是 属性值 注意 这个k是个变量,不加引号
}
// 我们使用 for in 里面的变量 我们喜欢写 k 或者 key
</script>
内置对象导读
目标:
- 能够说出什么是内置对象
- 能够根据文档查阅指定API的使用方法
- 能够使用Math 对象的常用方法
- 能够使用Date对象的常用方法
- 能够使用Array对象的常用方法
- 能够使用String 对象的常用方法
内置对象是什么?
js中对象分为3种:自定义对象、内置对象、浏览器对象
内置对象就是指js语言自带的一些对象,这些对象供开发者使用,并提供了一些用的或是最基本而必要的功能(属性和方法)
查文档
MDN, Mozilla 开发者网络(MDA)提供了有关开放网络技术
(open Web)的信息,包括HTML, CSS和万维网及HTML5应用的API
MDN: https://developer.mozilla.org/zh-CN/
如何学习对象中的方法:
1.查阅该方法的功能
2.查看里面参数的意义和类型
3.查看返回值的意义和类型
4.通过demo进行测试
参数是中括号括起来的,表示可以不写
Math 对象
//Math 内置对象,不是一个构造函数,所以我们不需要用 new来来调用 而是直接使用里面的属性和方法即可
console.log(Math.PI); //一个属性 圆周率
console.log(Math.max(1,99,3)); //99
console.log(Math.max(-1,-10)); //-1
console.log(Math.max()); //-Infinity
//1.绝对值
console.log(Math.abs(1));
console.log(Math.abs('-1')); //1
console.log(Math.log('PINK')); //NaN
//2. 三个取整的方法
//(1)Math.floor() 向下取整 往最小了取值
//(2)Math.ceil() 向上取整
//(3)Math.round() 四舍五入 5是往大了取
console.log(Math.round(-1.5)); // -1 5是往大了取
案例: 得到两个数之间的随机数 并且包含这2个数
// Math.floor(Math.random() * (max - min + 1)) + min
function getRandom(min, max){
return Math.floor(Math.random() * (max - min + 1)) + min;
} // 学会使用内置对象的方法
console.log(getRandom(1,10));
案例:随机点名
var arr = ['张三', '李四', '王五', '张三疯'];
console.log(arr[getRandom(1, arr.length-1)]);
案例: 封装自己的数学对象 利用对象封装自己的数学对象 里面有 PI 最大值和最小值
//案例 封装自己的数学对象 利用对象封装自己的数学对象 里面有 PI 最大值和最小值
var myMath = {
PI:3.141592653,
max: function(){
var max = arguments[0];
for (var i = 1; i < arguments.length; i++){
if (arguments[i] > max){
max = arguments[i];
}
}
return max;
},
min: function(){
var min = arguments[0];
for (var i = 1; i < arguments.length; i++){
if (arguments[i] < min){
min = arguments[i];
}
}
return min;
}
}
// 调用对象
console.log(myMath.PI);
console.log(myMath.max(1,3,88));
console.log(myMath.min(2,99,45));
案例: 猜数字游戏
// 猜数字游戏
// 程序随机生成 1~10 之间的数组,并让用户输入一个数字,
//1. 如果大于该数字,就提示,数字大了,继续猜;
//2. 如果小于该数字,就提示数字小了,继续猜;
//3. 如果等于该数字,就提示猜对了,结束程序;
function getRandom(min, max){
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var random = getRandom(1,10);
while(true) {
var num = prompt('你来猜,输入1~10之间的一个数字');
if(num > random){
alert('你猜大了');
}else if(num < random){
alert('你猜小了');
}else{
alert('你猜对了');
break; // 退出整个循环结束程序
}
}
Date() 方法的使用
1. 获取当前时间必须实例化
var now = new Date(); // 如果没有给参数,则返回当前的时间
console.log(now);
2. Date() 构造函数的参数
如果括号里面有时间,就返回参数里面的时间,例如日期格式字符串为 ‘2019-5-1’, 可以写成 new Date(‘2019-5-1’) 或者 new Date(‘2019/5/1’)
案例:写当前日期 2022年 7月 14日 星期一
<script>
//格式化日期 年月日
var date = new Date();
console.log(date.getFullYear()); // 返回当前日期的年
console.log(date.getMonth() + 1);// 月份 返回的月份小1个月 记得月份 +1
console.log(date.getDate()); //返回的是几号
console.log(date.getDay()); //周一 返回的是 1, 周六返回的是6, 但是周日返回的是0
// 我们写一个 2022年 7月 14日 星期一
var year = date.getFullYear();
var month = date.getMonth() + 1;
var dates = date.getDate();
var arr = ['星期日', '星期一' ,'星期二', '星期三', '星期四', '星期五', '星期六'];
var day = date.getDay();
console.log('今天是' + year + '年' + month + '月' + dates + '日 ' + arr[day] );
</script>
// 今天是2022年7月5日 星期二
案例: 封装一个函数返回当前的时间
function getTime(){
var time = new Date();
var h = time.getHours();
h = h < 10 ? '0' + h : h; // 补0
var m = time.getMinutes();
m = m < 10 ? '0' + m : m; //补0
var s = time.getSeconds();
s = s < 10? '0' + s : s;
return h + ':' + m + ':' + s;
}
console.log(getTime()); //07:21:08
获取日期的总的毫秒形式(时间戳)
Date 对象是基于1970年1月1日(世界标准时间)起的毫秒数
我们经常利用总的毫秒数来计算时间,因为它更精确
//获取Date总的毫秒数(时间戳)
//1.通过 valueOf() getTime()
var date = new Date();
console.log(date.valueOf());
console.log(date.getTime());
//2.简单写法(最常用的写法)
var date1 = +new Date(); //+new Date() 返回的就是总的毫秒数
console.log(date1);
// 3. H5 新增的 获得总的毫秒数
console.log(Date.now());
倒计时
① 核心算法: 输入的时间减去现在的时间就是剩余的时间,即倒计时,但是不能拿时分秒相减,比如 05分减去25分,结果会是负数的
②用时间戳来做。用户输入时间总的毫秒数减去现在时间的总的毫秒数,得到的就是剩余时间的毫秒数。
③ 把剩余时间总的毫秒数转换为天、时、分、秒
转换公式如下:
- d = parseInt(总秒数/60/60/24); 计算天数
- h = parseInt(总秒数/60/60%24); // 计算小时
- m = pareInt(总秒数/60%60); // 计算分数
- s = pareInt(总秒数%60); // 计算当前秒数
<script>
//倒计时
function countDown(time){
var nowTime = +new Date();
var inputTime = +new Date(time);
var time = (inputTime - nowTime)/1000; // 毫秒换算秒
var d = parseInt(time/60/60/24);
d = d < 10 ? '0' + d : d;
var h = parseInt(time/60/60%24);
h = h < 0 ? '0' + h : h;
var m = parseInt(time/60%60);
m = m < 0 ? '0' + m : m;
var s = parseInt(time%60);
return d + '天' + h + '时' + m + '时' + s + '秒';
}
console.log(new Date());
console.log(countDown('2022-7-8 18:00:00'));
//Tue Jul 05 2022 09:35:53 GMT+0800 (中国标准时间)
//26 03天8时24时6秒
</script>
数组对象
<script>
//创建数组 new Array 或是 数组字面量 []
// 1.字面量
var arr = [1,2,3];
// 2. new Array
var arr1 = new Array(); // 创建了一个空的数组
var arr2 = new Array(2); // 这个2表示 数组的长度为2,里面有2个空的数组元素
var arr3 = new Array(2,3); // 等价与[2,3] 这样写表示里面有2个数组元素,是2 和 3
//检测是否为数组 instanceof 运算符
var arr = [];
var obj = {};
console.log(arr instanceof Array);
console.log(obj instanceof Array);
//检测是否为数组 Array.isArray 方法
console.log(Array.isArray(arr));
console.log(Array.isArray(arr));
</script>
创建数组
//创建数组 new Array 或是 数组字面量 []
// 1.字面量
var arr = [1,2,3];
// 2. new Array
var arr1 = new Array(); // 创建了一个空的数组
var arr2 = new Array(2); // 这个2表示 数组的长度为2,里面有2个空的数组元素
var arr3 = new Array(2,3); // 等价与[2,3] 这样写表示里面有2个数组元素,是2 和 3
检测是否为数组
//检测是否为数组 instanceof 运算符
var arr = [];
var obj = {};
console.log(arr instanceof Array);
console.log(obj instanceof Array);
//检测是否为数组 Array.isArray 方法
console.log(Array.isArray(arr));
console.log(Array.isArray(arr));
添加删除数组元素方法
// 添加删除数组元素方法
// 1. push() 在我们数组的末尾 添加一个或者多个数组元素 push 推
var arr = [1, 2, 3];
console.log(arr.push(4, 'pink')); //5
console.log(arr); // (5) [1, 2, 3, 4, 'pink']
// (1)push() 是可以给数组追加新的元素
// (2)push() 参数直接写 数组元素就可以了
// (3)push() 完毕后,返回的结果是 新数组的长度
// (4) 原数组也会发生变化
// unshift 在数组的开头 添加一个或者多个数组元素
arr.unshift('red', 'purple');
console.log(arr);
// (1) unshift 是可以给数组追加新的元素
// (2) unshift() 参数直接写 数组元素就可以了
// (3)unshift() 完毕后,返回的结果是 新数组的长度
// (4) 原数组也会发生变化
// 删除数组元素
// pop() 它可以删除数组的最后一个元素
console.log(arr.pop());
console.log(arr);
//(1)pop()是可以删除数组的最后一个元素 记住遗传只能删除一个元素
//(2)pop() 没有参数
//(3)pop() 完毕之后,返回的结果是 删除的那个元素
//(4)原数组也会发生变化
//shift() 它可以删除数组的第一个元素
console.log(arr.pop());
console.log(arr);
//(1)shift() 它可以删除数组的第一个元素 记住一次只能删除一个元素
//(2)shift() 没有参数
//(3)shift() 完毕之后,返回的结果是 删除的那个元素
//(4)原数组也会发生变化
- 案例: 筛选数组
//案例 筛选数组 有一个包含工资的数组[1500, 1200, 2000,2100,1800],把工资中超过2000的删除,剩余的放到新数组里
var arr = [1500, 1200, 2000,2100,1800];
var newArr = [];
for (var i = 0; i < arr.length ; i++){
if(arr[i] < 2000){
//newArr[newArr.length] = arr[i];
newArr.push(arr[i]);
}
}
console.log(newArr);
数组排序
//数组排序
//1.翻转数组
var arr = ['pink', 'red', 'blue'];
arr.reverse();
console.log(arr);
//2. 数组排序(冒泡排序)
var arr1 = [13,14,2,6];
arr1.sort(function(a,b){
//return a-b; // 升序的顺序排序
// return b-a; // 降序的顺序排序
})
console.log(arr1);
获取数组索引引导方法
// 获取数组索引引导方法 indexOf(数组元素) 作用是返回该数组元素的索引号 从前面开始查找
// 它只返回第一个满足条件的索引号
// 它如果在该数组里面找不到元素,则返回的是-1
var arr = ['red', 'green', 'blue', 'pink'];
console.log(arr.indexOf('blue')); //2
//lastIndexOf(数组元素) 作用是返回该数组元素的索引号 从后面开始查找
console.log(arr.lastIndexOf('blue'));//2
数组去重
- ①目标: 把旧数组里面不重复的元素选取出来放到新数组中,重复的元素只保留一个
- ②核心算法: 我们遍历旧数组,然后拿着旧数组元素去查询新数组,如果该数组元素在新数组里面没有出现过,我们就添加,否则不添加。
- ③我们怎么知道该元素没有存在?利用新数组indexOf(数组元素),如果返回时 -1, 则说明新数组里面没有该元素
旧数组[‘c’, ‘a’, ‘b’ , ’ a’, ‘d’ ]
新数组[ ]
<script>
//数组去重
//①目标: 把旧数组里面不重复的元素选取出来放到新数组中,重复的元素只保留一个
//②核心算法: 我们遍历旧数组,然后拿着旧数组元素去查询新数组,如果该数组元素在新数组里面没有出现过,我们就添加,否则不添加。
//③我们怎么知道该元素没有存在?利用新数组indexOf(数组元素),如果返回时 -1, 则说明新数组里面没有该元素
//封装一个 去重的函数 unique 独一无二的
function unique(arr){
var newArr = [];
for(var i = 0; i < arr.length; i++){
if(newArr.indexOf(arr[i]) === -1){
//newArr[newArr.length] = arr[i];
newArr.push(arr[i]);
}
}
return newArr;
}
var arr = ['a', 'b', 'c', 'd', 'e', 'f', 'a', 'c', 'd'];
console.log(unique(arr)); // (6) ['a', 'b', 'c', 'd', 'e', 'f']
</script>
数组转字符串
<script>
//数组转换为字符串
//1. arr.toString()
var arr = [2 ,3 , 5];
console.log(arr.toString()); // 是以逗号分隔 2,3,5
//2. arr.join(分隔符) 默认以逗号分隔, 也可以自定义分隔符分隔
console.log(arr.join()); //2,3,5
console.log(arr.join('-')); //2-3-5
console.log(arr.join('$')); //2$3$5
</script>
课后
字符串对象
基本包装类型
字符串不可变
根据字符返回位置
字符串所有的方法,都不会修改字符串本身(字符串是不可变的,操作完成会返回一个新的字符串
方法名 | 说明 |
---|---|
indexOf(‘要查找 字符’, 开始的位置) | 返回指定内容在原字符串中的位置,如果找不到就返回-1,开始的位置是index索引号。 |
lastIndexOf() | 从后往前找,只找第一个匹配的 |
var str = '改革春风吹满地,春天来了';
console.log(str.indeOf('春'));
console.log(str.indexOf('春',3)); //从索引号是 3 的位置开始往后查找
案例:返回字符位置及字符出现的次数
查找字符串‘abcdefgoxyozzophg’中所有o出现的位置及次数
思路:
①核心算法:先查找第一个o出现的位置
②然后只要indexOf返回的结果不是-1, 就继续往后查找
③因为indexOf只能查找到第一个,所以后面的查找,利用第二个参数,当前索引加1,从而继续查找
<script>
var str = 'avbcsdsdsdodosas';
var index = str.indexOf('s');
var num = 0;
while(index !== -1){
console.log(index);
num ++;
index = str.indexOf('s', index + 1);
}
console.log('s出现的次数是:' + num);
</script>
案例:根据位置返回字符
方法名 | 说明 | 使用 |
---|---|---|
charAt(index) | 返回指定位置的字符(index字符串的索引号) | str.charAt(0) |
charCodeAt(index) | 获取指定位置处字符的ASCII码(index索引号) | str.chartCodeAt(0) |
str[index] | 获取指定位置处的字符 | HTML5, IE8+ 支持, 和charAt()等效 |
计算某个字符出现的次数
//核心思路:
//先准备一个大的篮子,从字符串里取出一个字符,记下字符的名称,出现第一次,次数为1,依次遍历每个字符,如果遍历到的字符前面有出现过,则出现次数加1,否则出现次数为1。
//字符名称就是属性,出现次数就是值,可以看做是一个键值对,用对象来容纳多个键值对。
//因此,可以创建一个空对象,依次往里面放入键值对。最后打印所求的某个字符串的出现的次数,相当于打印某个属性的值。
var str = 'abcoefoxyozzopp';
var o = {};
for (var i = 0; i < str.length; i++){
var chars = str.charAt(i);
if (o[chars]){
o[chars] += 1;
}else{
o[chars] = 1;
}
}
console.log(o['o']);
console.log(o);
计算出现次数最多的字符
//核心思路:
//先创建一个最大值,初始值为0,创建一个空的字符串,遍历整个对象,遍历一个,记下属性,记下,该值和初始最大值进行比较,若该值大于初始最大值,则初始最大值等于该值,空字符串等于该属性。
//继续下一次遍历,记下属性和值,将值与最大值比较,若该值大于最大值,则最大值等于该值,最大值对应的属性为该值的属性。
//最后打印出最大值和其属性
var a = '';
var num = 0;
for (key in o){
if (o[key] > num){
num = o[key];
a = key;
}
};
console.log(a, num);
字符串操作方法(重点)
方法名 | 说明 |
---|---|
concat(str1,str2,str3…) | concat()方法用于连接两个或多个字符串。拼接字符串,等效于+, + 更常用 |
substr(start,length) | 从start 位置开始(索引号), length取的个数,重点记这个 |
slice(start,end) | 从start位置开始,截取到end位置, end取不到(他们俩都是索引号) |
substring(start,end) | 从start位置开始,截取到end位置, end 取不到 基本和slice 相同,但是不接受负值 |
替换字符串以及转换为数组
<script>
//1.替换字符 replace('被替换的字符', '替换为字符') 它只会替换第一个字符
var str = 'andy';
console.log(str.replace('a', 'b'));
//有一个字符串,要求把里面所有的o 替换为 *
//思路:首先,遍历每一个字符,遇到字符为o, 就替换为*
// while循环
var str1 = 'abcdeoooedoef';
while (str1.indexOf('o') !== -1) {
str1 = str1.replace('o', '*');
}
console.log(str1);
// for 循环
for (var i = 0; i < str1.length; i++){
if (str1[i] == 'o'){
str1 = str1.replace('o', '*');
}
}
console.log(str1);
//2. 字符转换为数组 split('分隔符') 前面我们学过 join 把数组转换为字符串
var str2 = 'red, pink, blue'; // 分隔符是','
console.log(str2.split(',')); // ['red', 'pink', 'blue']
var str3 = 'red&pink&blue'; // 分隔符是'&'
console.log(str3.split('&')); // ['red', 'pink', 'blue']
</script>
简单数据类型和复杂数据类型
简单数据类型 又叫做 基本数据类型 或者值类型,复杂数据类型又叫做 引用类型。
- 简单数据类型:值类型 简单数据类型/基本数据类型, 在存储时变量中存储的值本身,因此叫做值类型 string, number, boolean, undefined, null.
// 简单数据类型 null 返回的是一个空的对象 object
var timer = null;
console.log(typeof timer);
// 如果有个变量我们以后打算存储为对象,暂时没想好放啥,这时候就给 null
- 复杂数据类型: 引用数据类型, 在存储变量中存储的仅仅是地址(引用),因此叫做引用数据类型,通过 new 关键字创建的对象(系统对象、自定义对象),如Object、 Array、 Date 等
堆栈空间分配区别:
1.栈(操作系统):由操作系统自动释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;简单数据类型存放到栈里面
2、堆(操作系统): 存放复杂类型(对象), 一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
复杂数据类型存放到堆里面。
js中没有堆和栈的概念。
第二章:DOM和BOM
- DOM简介
- 获取元素
- 事件基础
- 节点操作
1 DOM基础 ---- 元素操作
1.1 DOM是什么?
- DOM, "Document Object model”(文档对象模型),它是由W3C定义的一个标准
- DOM操作,可以简单理解成:元素操作;
- 实际开发中,常见的DOM操作:
(1)改变这个元素的颜色
(2)点击这个元素实现某些效果
(3)直接把这个元素删除 - 在DOM中,我们使用“树形结构”来表示一个页面, 在这个树上,html标签就是树根,叫做根元素。html标签内部有 head、body这两个标签,这两个标签位于同意层,所以也叫做兄弟节点。html标签是作为这两个兄弟节点的父节点。head标签内部有两个标签,title和meta, 这两个标签也是作为head标签的子节点,所以,head就是这两个标签的父节点,这两个标签之间是兄弟节点。用这种简单的族谱关系,可以很清楚的把一个页面表示出来。
记住:每一个元素就是一个节点,而每一个节点就是一个对象。在操作元素时,其实就是把这个元素看成一个对象,然后使用这个对象的属性和方法来进行相关操作。
1.2 节点类型
DOM节点共有12种类型,记住常见的以下3种:
(1)元素节点
(2)属性节点
(3)文本节点
节点与元素是不一样的概念,节点包括元素
Javascript中,用nodeType属性来判断一个节点的类型
表1 不同节点的nodeType属性值123
节点类型注意事项:
- 一个元素就是一个节点,这个节点称之为“元素节点”;
- 属性节点和文本节点看起来像是元素节点的一部分,但实际上,它们是独立的节点,并不属于元素节点;
- 只有元素节点才可以拥有子节点,属性节点和文本节点都无法拥有子节点。
- 元素的节点是被当成一个对象来处理,既然是对象,就有自己的属性
1.3 获取元素(获取元素的节点)
获取html元素:document.documentElement 返回一个html元素对象
通过id 获取元素
<script>
//通过id 获取元素
var t1 = document.getElementById('time');
// 打印属性和方法 console.dir()
console.dir(t1);
console.log(t1.tagName);
</script>
通过标签名获取元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function()
{
var oDiv = document.getElementById("main");
oDiv.style.color="red";
var oDiv = document.getElementsByTagName("div");
for(var i=0; i<oDiv.length;i++)
{
oDiv[i].style.color="red";
}
var oDiv = document.getElementsByClassName("yuansu");
for(var i=0; i<oDiv.length;i++)
{
oDiv[i].style.color="blue";
}
var oDiv = document.querySelector(".yuansu");
oDiv.style.color="red";
var oDiv = document.querySelectorAll(".yuansu");
for(var i=0; i<oDiv.length;i++)
{
oDiv[i].style.color="yellow"
}
}
</script>
</head>
<body>
<div class="yuansu">选择了就不要回头看</div>
<div class="yuansu">选择了就不要回头看</div>
<div id="main">选择了就不要回头看</div>
</body>
</html>
1.4 DOM操作 - 创建元素
(1) 创建一个简单的节点
- var e2 = document.getElementsById(“id 名”) ;获取已有元素
- var e1 = document.createElement(“元素名”) ; 创建元素节点
- var txt = document.createTextNode(“文本内容”); 创建文本节点
- e1.appendChild(txt); 把文本插入元素节点
- e2.appendChild(e1); 把组装好的元素插入到已有元素e2中
(2)创建一个带有属性的节点
DOM对象有属性和方法,属性用A.B, 方法用A.function()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function()
{
// 创建简单的节点,元素加文本
var e2 = document.getElementById("jianchi");
var e1 = document.createElement("strong");
var txt = document.createTextNode("键盘敲烂");
e1.appendChild(txt);
e2.appendChild(e1);
// 创建复杂节点,添加元素的属性.首先创建一个DOM对象,添加对象的属性.和方法()
var oBody = document.body;
var oInput = document.createElement("input");
oInput.id = "submit";
oInput.type = "button";
oInput.value = "提交";
oBody.appendChild(oInput);
}
</script>
</head>
<body>
<div id="jianchi"></div>
</body>
</html>
1.5 插入元素
(1)A.appendChild(B); 把一个新元素插入到父元素的内部子元素的“末尾”。
(2)insertBefore()将一个新元素插入到父元素中的某一个子元素“之前”。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script>
window.onload = function()
{
// 首先获取插入按钮
var oBtn = document.getElementById("btn");
// 然后为按钮添加一个点击事件
oBtn.onclick = function()
{
var oUl = document.getElementById("list");
var oTxt = document.getElementById("txt");
// 将文本框的内容转换为“文本节点”
var textNode = document.createTextNode(oTxt.value);
// 动态创建一个li元素
var oLi = document.createElement("li");
// 将文本节点内容添加到li元素中去
oLi.appendChild(textNode);
// 将li元素插入到ul元素中
oUl.appendChild(oLi)
// 将li元素插入到ul元素的第一个元素之前
oUl.insertBefore(oLi,oUl.firstElementChild);
};
}
</script>
<body>
<ul id="list">
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
<li>vue.js</li>
</ul>
<input id="txt" type="text"> <input id="btn" type="button" value="插入" >
</body>
</html>
1.6 删除元素
A.removeChild(B);
<!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>
<script>
window.onload = function()
{
// 首先获取这个按钮
// var oBtn = document.getElementById("btn");
// oBtn.onclick = function()
// {
// var oUl = document.getElementById("list");
// oUl.removeChild(oUl.lastElementChild);
// }
// 删除整个列表,整个列表是body元素的子元素,可以通过获取Body元素,然后删除body元素中的子元素
var oBtn = document.getElementById("btn");
oBtn.onclick = function()
{
var oUl = document.getElementById("list");
document.body.removeChild(oUl);
}
}
</script>
<body>
<ul id="list">
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
<li>Vue.js</li>
</ul>
<input id="btn" type="botton" value="删除"/>
</body>
</html>
1.7 复制元素
obj.cloneNode(bool);
1.8 替换元素
A.replaceChild(new,old);
2. DOM 进阶 --属性操作
HTML属性操作,指的是使用JavaScript来操作一个元素的HTML属性。如下面的input元素,HTML属性操作指的就是操作它的id、type、value等,其他元素也类似。
<input id=“btn” type=“button” value=“提交”/>
JS 操作HTML元素属性
- 获取HTML属性值
- 设置HTML属性值
JS操作HTML元素属性的方式
- 对象属性
- 对象方法
2.1 HTML属性操作
2.1.1 对象属性
获取HTML属性值—通过属性名来找到属性对应的值
语法: obj.attr
说明: obj是元素名,它是一个DOM对象。所谓的DOM对象,指的是使用getElementById()、getElementsByTagName()等方法获取的元素节点。
attr是属性名,对于一个对象来说,可以通过点运算符(.)来获取它的属性值。
设置HTML属性值
语法:obj.attr = “值”;
说明:obj是元素名,它一个DOM对象,attr是属性名。
2.1.2 对象方法
对象属性的方法,obj.attr, 只能获取元素中的固有属性,即HTML元素中本来就有的属性,不能获取自定义的属性。自定义属性,即我们自己定义的属性,如添加一个 data=“好好学习”,这种元素中本来没有的属性,对象属性的方法就不能用,只能使用对象方法来获取。
对象方法有:
- obj.getAttribute(“attr”) 获取元素的某个属性的值,可以是“固有属性值”,也可以获取“自定义属性值”。
- obj.setAttribute(“attr”,“值”) 设置元素的某个属性的值。
- obj.removeAttribute(“attr”) 删除元素的某个属性。removeAttribute()更多情况下是结合class属性来“整体”控制元素的样式属性的。
- obj.hasAttribute(“attr”) 判断元素是否含有某个属性。判断元素是否含有某个属性。
案例1: 分时显示不同图片,显示不同问候语
- 根据不同时间,页面显示不同图片,同时显示不同的问候语
- 如果上午时间打开页面,显示上午好,显示上午的图片
- 如果下午时间打开页面,显示下午好,显示下午的图片
- 如果晚上时间打开页面,显示晚上好,显示晚上的图片
案例分析
①根据系统不同时间来判断,所以需要用到日期内置对象
②利用多分支语句来设置不同的图片
③需要一个图片,根据时间修改图片,就需要用到操作元素src元素
④需要一个div元素,显示不同问候语,修改元素内容即可
2.2 CSS属性操作
getComputedStyle(obj).attr 获取CSS元素属性值
语法:getComputedStyle(obj).attr
例如: alert(getComputedStyle(oBox).backgroundColor);
getComputedStyle()方法其实有两种写法:getComputedStyle(obj).attr和getComputed Style(obj)["attr"]。
凡是对象的属性都有这两种写法,如oBtn.id可以写成oBtn["id"],document.getElementById("btn")可以写成document["getElementById"]("btn"),以此类推
- 设置值
(1)语法: obj.style.attr = "值"; obj表示DOM对象,attr表示CSS属性名,采用的同样是“骆驼峰”型。
obj.style.attr 等价于obj.style["attr"],如oDiv.style.width等价于oDiv.style["width"]。
例如: oBox.style.backgroundColor = "lightskyblue";
(2)对于复合属性(如border、font等)来说,操作方式也是一样的,举例如下。
oBox.style.border = "2px solid blue";
(3)可以使用cssText属性来同时设置多个CSS属性,这也是在元素的style属性中添加的。
obj表示DOM对象,cssText的值是一个字符串。
oDiv.style.cssText = "width:100px;height:100px;border:1px solid gray;";
2.3 DOM遍历
DOM遍历就是查找元素。
(1)查找父元素 obj.parentNode;
oTd[i].onclick = function()
{
var oParent = this.parentNode; #this表示当前对象/元素
oParent.style.color="white";
}
(2)查找子元素
childNodes、firstChild、lastChild(不常用)
children、firstElementChild、lastElementChild(常用)
childNodes获取的是所有的子节点。注意,这个子节点是包括元素节点以及文本节点的。而children获取的是所有的元素节点,不包括文本节点。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
window.onload = function()
{
var oUl = document.getElementById("list");
var chirldNodesLen = oUl.childNodes.length;
var childrenLen = oUl.children.length;
alert("childNodes的长度为:" + childNodesLen + "\n" + "children的长度为:” + childrenLen)
}
</script>
<body>
<ul id="list">
<li>HTML</li>
<li>CSS</li>
<li>Javasript</li>
</ul>
</body>
</html>
childNodes包括3个子元素节点和4个子文本节点。每一个li元素都处于不同行,每一个换行符都是一个空白节点,JavaScript会把这些空白节点当成文本节点来处理.
因此, children.length获取的是元素节点的长度,返回结果为3,childNodes.length获取的是子节点的长度,返回结果是7.
oUl.removeChild(oUl.lastElementChild); #删除元素节点
oUl.removeChild(oUl.lastChild); #删除节点,空白文本节点或元素节点
(3)查找兄弟元素
previousSibling、nextSibling(不常用)
previousElementSibling、nextElementSibling(常用)
#查找第二个子元素的前面一个兄弟元素节点
var preElement = oUl.children[2].previousElementsSibling;
#删除该元素节点
oUl.removeChild(preElement);
2.4 改变元素内容 innerHTML和innerText
innerHTML属性很方便地获取和设置一个元素的“内部元素”
innerText属性获取和设置一个元素的“内部文本”。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
window.onload = function()
{
document.body.innerHTML = '<img class="pic" src="./haizei.png" style="border:1px solid silver"/>' ;
}
</script>
</head>
<body>
</body>
</html>
innerHTML获取的是元素内部所有的内容,包括html,同时保留空格和空行,而innerText获取的仅仅是文本内容,去除html标签,同时空格和换行也会去掉
3 事件基础
执行事件的步骤:
- ①获取事件源
- ②绑定事件类型 注册事件
- ③添加事件处理程序
(1)鼠标事件
(2)键盘事件
(3)表单事件
(4)编辑事件
(5)页面事件
3.1 事件的调用方式
- 在script标签中调用
- 在元素中调用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
function alertMet()
{
alert("知之为知之,不知为不知,是知也");
}
</script>
</head>
<body>
<input type="button" onclick="alertMet()" value="弹出">
</body>
</html>
#或直接写为:
<input type="button" onclick="alert('知之为知之,不知为不知,是知也')" value="弹出">
3.2 鼠标事件
我们可以为任何元素添加鼠标单击事件!
3.3 键盘事件
案例:统计输入字符的长度
实现原理:每输入一个字符,我们都需要敲击一下键盘;每次输入完成,也就是松开键盘时,都会触发一次onkeyup事件此时计算字符串的长度。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
window.onload = function(){
var oTxt = document.getElementById("txt");
var oNum = document.getElementById("num");
oTxt.onkeyup = function()
{
var str = oTxt.value;
oNum.innerHTML = str.length;
};
}
</script>
</head>
<body>
<input type="text" id="txt"/>
<div>字符串长度为:<span id="num">0</span></div>
</body>
</html>
3.4 表单事件
并不是所有的HTML元素都有焦点事件,具有“获取焦点”和“失去焦点”特点的元素只有两种。
▶ 表单元素(单选框、复选框、单行文本框、多行文本框、下拉列表)。
▶ 超链接。
判断一个元素是否具有焦点很简单,我们打开一个页面后按【Tab】键,能够选中的就是具有焦点特性的元素。
3.4.1 onfocus 和 onblur属性
案例:单行文本框搜索框,在文本框中没有输入值的时候,当失去焦点的时候,提示文字就会出现。当有输入文本内容时,获得焦点时,文本框的值为保留的输入值。
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
window.onload = function(){
var oSearch = document.getElementById("search");
var oBtn = document.getElementById("btn");
// 获取焦点
oSearch.onfocus = function() {
if(this.value =="百度一下,你就知道")
{
this.value = "";
}
};
// 失去焦点
oSearch.onblur = function(){
if(this.value == "")
{
this.value = "百度一下,你就知道"
}
};
}
</script>
</head>
<body>
<input type="text" id="search" value="百度一下,你就知道">
<input type="button" id="btn" value="搜索">
</body>
</html>
补充:自动获取焦点的方法: obj.focus()
3.4.2 onselect 属性
文本框内容设置:
单行文本框的内容:在value属性中设置
多行文本框内地:在标签中设置
举例:当选择文本框内容时出现提示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
window.onload = function(){
var oTxt1 = document.getElementById("txt1");
var oTxt2 = document.getElementById("txt2");
oTxt1.onselect = function(){
alert("你选中了单行文本框的内容");
};
oTxt2.onselect = function(){
alert("你选中了多行文本框的内容");
};
}
</script>
</head>
<body>
<input type="text" id="txt1" value="单行文本框的内容在value属性中设置"><br />
<textarea id="txt2" cols="20" rows="5">多行文本框的内容是在标签中设置的,这一点一定要记住</textarea>
</body>
</html>
需要区别的是,select()方法,是一个方法,onselect是一个属性,它是用于事件操作的。select()方法表示,点击文本框时,自动帮我们把文本框内的内容全选中。语法: obj.select();
3.4.3 onchange属性 具有多个选项的表单元素
(1)单选框选择某一项时触发
(2)复选框选择某一项时触发
(3)下拉列表项选择某一项时触发
案例1:
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
window.onload = function(){
// getElementsByName获取的是一个类数组,要用for循环遍历
var oFruit = document.getElementsByName("fruit");
var oP = document.getElementById("content");
for (var i=0; i<oFruit.length;i++)
{
oFruit[i].onchange = function()
{
if(this.checked)
{
oP.innerHTML = "你选择的是:" + this.value
}
};
}
}
</script>
</head>
<body>
<div>
<label><input type="radio" name="fruit" value="苹果"/></label>
<label><input type="radio" name="fruit" value="香蕉" /></label>
<label><input type="radio" name="fruit" value="西瓜"></label>
</div>
<div>
<p id="content">你选择的是:</p>
</div>
</body>
</html>
复选框
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script>
window.onload = function () {
var oSelectAll = document.getElementById("selectAll");
var oFruit = document.getElementsByName("fruit");
oSelectAll.onchange = function () {
//如果选中,即this.checked返回true
if (this.checked) {
for (var i = 0; i < oFruit.length; i++) {
oFruit[i].checked = true;
}
} else {
for (var i = 0; i < oFruit.length; i++) {
oFruit[i].checked = false;
}
}
};
}
</script>
</head>
<body>
<div>
<p><label><input id="selectAll" type="checkbox"/>全选/反选:</label></p>
<label><input type="checkbox" name="fruit" value="苹果" />苹果</label>
<label><input type="checkbox" name="fruit" value="香蕉" />香蕉</label>
<label><input type="checkbox" name="fruit" value="西瓜" />西瓜</label>
</div>
</body>
</html>
下拉列表
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script>
window.onload = function () {
var oList = document.getElementById("list");
oList.onchange = function () {
var link = this.options[this.selectedIndex].value;
window.open(link);
};
}
</script>
</head>
<body>
<select id="list">
<option value="https://music.163.com">网易云</option>
<option value="https://www.epubit.com">异步社区</option>
<option value="http://www.ptpress.com.cn">人邮官网</option>
</select>
</body>
</html>
3.5 编辑事件 防止复制
- oncopy 防止页面内容被复制
- onselectstart 防止页面内容被选取
- oncontextmenu 禁止鼠标右键
3.6 页面事件
- onload: 表示文档加载完成后再执行的一个事件
- onbeforeunload:离开页面之前触发的一个事件
4 事件进阶
4.1事件监听器
在Javascript中,如果要给元素添加一个事件,可采用以下两种方式。
▶ 事件处理器 obj.onclick = function () {……};
▶ 事件监听器 obj.addEventListener(“click”, function () {……);}, false);
前面学的给元素添加事件的方式就是时间处理器的方式,这种方式不能为一个元素添加多个相同的事件。为一个元素添加多个相同的事件,需要用事件监听器的方式。
事件监听器”,指的是使用addEventListener()方法为一个元素添加事件,我们又称之为“绑定事件”
obj.addEventListener(type , fn , false)
- obj是一个DOM对象,指的是使用getElementById()、getElementsByTagName()等方法获取的元素节点。
- type是一个字符串,指的是事件类型。如单击事件用click,鼠标移入用mouseover等。一定要注意,这个事件类型是不需要加上“on”前缀的。
- fn是一个函数名,或是一个匿名函数。
- false表示事件冒泡阶段调用。
- fn的写法:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script>
window.onload = function () {
var oBtn = document.getElementById("btn");
oBtn.addEventListener("click", alertMes, false);
#function为具体函数如alertMes,需要定义一下
function alertMes() {
alert("JavaScript");
}
}
</script>
</head>
<body>
<input id="btn" type="button" value="按钮"/>
</body>
</html>
解绑事件:
obj.removeEventListener(type , fn , false);
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script>
window.onload = function () {
var oP = document.getElementById("content");
var oBtn = document.getElementById("btn");
//为p添加事件
oP.addEventListener("click", changeColor, false);
//点击按钮后,为p解除事件
oBtn.addEventListener("click", function () {
oP.removeEventListener("click", changeColor, false);
}, false);
function changeColor() {
this.style.color = "hotpink";
}
}
</script>
</head>
<body>
<p id="content">绿叶学习网</p>
<input id="btn" type="button" value="解除" />
</body>
</html>
removeEventListener()方法只能解除“事件监听器”添加的事件,不能解除“事件处理器”添加的事件。如果想要解除“事件处理器”添加的事件,需要借助“obj.事件名 = null;”来实现;
4.2 this对象
哪个DOM对象(元素节点)调用了this所在的函数,那么this指向的就是哪个DOM对象
记住,在事件函数中,想要使用当前元素节点,我们尽量使用 this 来代替oBtn、oLi[i] 等等这种DOM对象的写法。
4.3 even对象
当一个事件发生的时候,这个事件有关的详细信息都会临时保存到一个指定的地方,这个地方就是event对象。每一个事件,都有一个对应的event对象.
5. window对象
- 在JavaScript中,一个浏览器窗口就是一个window对象。
- 一个窗口就是一个window对象,这个窗口里面的HTML文档就是一个document对象,document对象是window对象的子对象。
- window对象及其子对象:window对象及下面这些location、navigator等子对象,由于都是用于操作浏览器窗口的,所以我们又称之为“BOM”,也就是Browser Object Module(浏览器对象模型)
- window对象的常用方法:对于window对象,无论是它的属性,还是方法,都可以省略window前缀。如window.alert()可以简写为alert(),window.open()可以简写为open(),甚至window.document.getElementById()可以简写为document.getElementById(),
5.1 窗口操作
在JavaScript中,窗口常见的操作有两种:一种是“打开窗口”,另一种是“关闭窗口”.打开窗口和关闭窗口,在实际开发中经常用到。
5.1.1 打开窗口
- 语法: window.open(url, target);
- 说明:url指的是新窗口的地址,如果url为空,则表示打开一个空白窗口。空白窗口很有用,我们可以使用document.write()往空白窗口输出文本,甚至输出一个HTML页面;
target表示打开方式,它的取值根a标签中target属性的取值是一样的,常用取值有两个:_blank (默认值,表示在新窗口中打开) 和 _self(表示在当前窗口中打开)
举例:打开一个空白窗口:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
window.onload = function(){
var oBtn = document.getElementById("btn");
oBtn.onclick = function(){
// 打开一个空白窗口,这个操作的意义在于,可以把这个空白窗口赋值给一个变量,
// 这个变量也是一个window对象,获取该对象,即可对这个页面进行操作。
var opener = window.open();
// 新窗口下面有document子对象,借助document.write()方法来输出一个文本
opener.document.write("这是一个新的窗口");
// 为新窗口设置样式
opener.document.body.style.backgroundColor = "red";
};
}
</script>
</head>
<body>
<input type="button" id="btn" value="获取">
</body>
</html>
5.1.2 关闭窗口
- 语法: window.close()
该方法不接收任何的参数。
举例:实现打开一个新窗口,然后关闭该新窗口
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script>
window.onload = function () {
var btnOpen = document.getElementById("btn_open");
var btnClose = document.getElementById("btn_close");
// 先创建一个空白变量
var opener = null;
btnOpen.onclick = function () {
opener = window.open("http://www.lvyestudy.com");
};
btnClose.onclick = function () {
// 关闭新打开的窗口
opener.close();
}
}
</script>
</head>
<body>
<input id="btn_open" type="button" value="打开新窗口" />
<input id="btn_close" type="button" value="关闭新窗口" />
</body>
</html>
5.2 对话框
JavaScript中,对话框有3种:
- alert() 只用于提示文字,记住一点:在alert()中实现文本换行,用的是\n
alert("HTML\nCSS\nJavaScript");
- confirm(“提示文字”) 不仅提示文字,还提供确认。
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script>
window.onload = function () {
var oBtn = document.getElementById("btn");
oBtn.onclick = function () {
if (confirm("确定要跳转到绿叶首页?")) {
window.location.href = "http://www.lvyestudy.com";
} else {
document.write("你取消了跳转");
}
};
}
</script>
</head>
<body>
<input id="btn" type="button" value="回到首页"/>
</body>
</html>
- prompt(“提示文字”) 不仅会提示文字,还会返回一个字符串
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script>
window.onload = function () {
var oBtn = document.getElementById("btn");
oBtn.onclick = function () {
var name = prompt("请输入你的名字");
document.write("欢迎来到<strong>" + name + "</strong>");
};
}
</script>
</head>
<body>
<input id="btn" type="button" value="按钮"/>
</body>
</html>
5.3 定时器
指的是每隔一段时间就执行一次代码。
▶ setTimeout()和clearTimeout()。
在JavaScript中,我们可以使用setTimeout()方法来“一次性”地调用函数,并且可以使用clearTimeout()来取消执行setTimeout()。
setTimeout(code, time);
参数code可以是一段代码,可以是一个函数,也可以是一个函数名。
参数time是时间,单位为毫秒,表示要过多长时间才执行code中的代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
window.onload = function()
{
// 第一种:第一个参数是一段代码
setTimeout('alert("你已经看了2秒钟了")', 2000);
// 第二种:第一个参数是一个函数
setTimeout(function(){
alert("你已经看了2秒钟了")
}, 2000);
// 第三种:第一个参数是一个函数名
setTimeout(alertMet, 200);
// 定义一个函数,在函数内部弹出一个对话框
function alertMet()
{
alert("你已经看了2秒钟了")
}
}
</script>
</head>
<body>
<p>2秒后提示</p>
</body>
</html>
▶** setInterval和clearInterval()。**
使用setInterval()方法来“重复性”地调用函数,并且可以使用clearInterval()来取消执行setInterval()
setInterval(code, time);
setInterval()跟setTimeout()语法是一样的,唯一不同的是setTimeout()只执行一次,而setInterval()可以重复执行无数次
5.4 location对象 操作当前页面地址(URL)
5.5 navigator对象 获取浏览器的详细信息
6. document对象
document对象其实是window对象下的一个子对象,它操作的是HTML文档里所有的内容.
document是浏览器为每个窗口内的HTML页面创建的对象。通过document对象,我们可以操作页面的元素,这些操作又被统称为“DOM(文档对象模型)”.
由于window对象是包括document对象的,所以我们可以“简单”地把BOM和DOM的关系理解成BOM包含DOM
6.1 document对象常用属性
document.forms、document.images、document.links这3个分别等价于下面3个,所以我们一般用document.getElementsByTagName来获取就行了,不需要记忆。
- document.URL 获取页面的当前地址
var url = document.URL;
document.write(url);
- document.referrer 获取用户在访问当前页面之前所在页面的地址
6.2 document常用的方法
document.write()不仅可以输出文本,还可以输出标签。
document.write()都是在body标签内输出内容的。
document.writeln("js") 等同于 document.write("js\n");