文章目录
一、JS概念
1、变量的命名规则和命名规范
规则: 必须遵守的,不遵守就是错
- 变量只能由 数字 字母 下划线 美元符 组成
- 变量不能由数字开头
- 严格区分大小写
- 不能使用关键字或者保留字
- 不要出现空格
规范: 建议遵守的(开发者默认),不遵守不会报错
6. 变量名尽量有意义(语化)
7. 遵循驼峰命名规则,由多个单词组成的时候,从第二个单词开始首字母大写
8. 不要使用中文
2、数据类型
1、概念:
是指我们存储在内存中的数据的类型。通常分为两类:基本类型和复杂类型
2、数据类型分类:
基本类型:
- Number:整数、浮点数、十进制数、十六进制、八进制、二进制
- String :字符串类型
- Boolean :只有true和false两个值
- Undefined:只有undefined一个值 ,声明了,但是未赋值
- Null :只有null一个值,表示无
- Symbol:
复杂类型:
3、判读数据类型:
使用typeof关键字来进行判断
第一种使用方式:
var n1 = 100;
console.log(typeof n1)
第二种使用方式:
var s1 = 'abcdeffg';
console.log(typeof(s1))
4、类型装换
1、其他数据类型装换成数值
1.Number(变量)
语法: Number(要转换的内容)
结果: 转换好数值类型的结果
- 可以把一个变量强制转换成数值类型
- 可以转换小数,会保留小数
- 可以转换布尔值
- 遇到不可转换的都会返回 NaN(非法数字),NaN也是Number类型的,
2.parseInt(变量)
语法: parseInt(要转换的内容)
- 从第一位开始检查,是数字就转换,会自动去掉不是数字的内容
- 开头就不是数字,那么直接返回 NaN
- 不认识小数点,只能保留整数
3.parseFToat(变量)
语法: parseFToat(要转换的内容)
- 从第一位开始检查,是数字就转换,会自动去掉不是数字的内容
- 开头就不是数字,那么直接返回 NaN
- 认识一次小数点
4.除了加法以外的数学运算
- 运算符两边都是可运算数字才行
- 如果运算符任何一遍不是一个可运算数字,那么就会返回 NaN
- 加法不可以用
2、其他数据类型装换成字符串
1.变量.tostring()
语法: tostring(要转换的内容)
有一些数据类型不能使用 tostring()方法,比如undefined 和null
2.string(变量)
语法: string(要转换的内容)
所有数据类型都可以
3.使用加法运算
在JS里面,+由两个含义
字符串拼接: 只要+任意一边是字符串,就会进行字符串拼接
加法运算: 只有+两边都是数字的时候,才会进行数学运算
3 其他数据类型转成布尔
1.Boolean(变量)
在js中,只有 " "、0、null、undefined、NaN,这些是 false其余都是true
5、运算符
就是在代码里面进行运算的时候使用的符号,不光只是数学运算,我们在 js 里面还有很多的运算方式
1、数学运算符
1.+
只有符号两边都是数字的时候才会进行加法运算
只要符号任意一边是字符串类型,就会进行字符串拼接
2.-
会执行减法运算
会自动把两边都转换成数字进行运算
3.*
会执行乘法运算
会自动把两边都转换成数字进行运算
4./
会执行除法运算
会自动把两边都转换成数字进行运算
5.% 取余
2、 比较运算符
注意: “ ”默认值为0,undefined、NaN与谁比较都是false,如:
console.log(true==1) //true
console.log(""==0) //true
console.log(undefined==0) //false
console.log(""===0) //false
3、逻辑运算符
4、自增自减运算符
1、++
分成两种: 前置++ 和 后置++
前置++,会先把值自动 +1,在返回
var a = 10;
console.1og(++a);
// 会返回 11,并且把 a 的值变成 11
后置++,会先把值返回,在自动+10
var a = 10:
console.1og(a++);
// 会返回 10,然后把 a 的值变成 11
2.–
进行自减运算
分成两种,前置- - 和 后置- -
和 ++ 运算符道理一样
5、三元运算符
三元运算,就是用 两个符号 组成一个语句
语法: 条件 ? 条件为 true 的时候执行:条件为 false 的时候执行
var age = 18;
age >= 18 ? alert('已经成年') : alert('没有成年')
二、函数知识
1、函数的概念
对于JS来说,函数就是把任意一段代码放在一个盒子里面,在用的时候直接执行这个盒子里面的代码就行
2、函数的定义
有两种定义方式声明式和赋值式
1、声明式
使用function这个关键字来声明一个函数
语法:
function fn(){
//一段代码
}
2、赋值式
首先使用var定义一个变量,把一个函数当中值直接赋值给这个变量就可以了
语法:
var fn = function(){
//一段代码
}
//不需要在function后面书写函数的名字了,因为在前面已经有了
区别: 声明式可以先调用在定义,但是赋值式必须是先定义后调用
3、预解析
1、概念
JS是一个解释型语言,就是在代码执行之前,先对代码进行通读和解释,然后在执行代码,也就是说,JS代码在运行的时候,会经历两个环节:解释代码和执行代码
解释代码:
因为是在所有代码执行之前进行解释,所以叫预解析(预解释)
2、需要解释的内容有两个:
1、声明式函数:
在内存中先声明有一个变量名的函数名,并且这个名字代表的内容是一个函数
2、var 关键字:
在内存中先声明有一个变量名(可以将变量名提到第一行)
4、作用域
什么是作用域,就是一个变量可以生效的范围变量不是在所有地方都可以使用的,而这个变量的使用范围就是作用域
1、全局作用域
- 全局作用域是最大的作用域
- 在全局作用域中定义的变量可以在任何地方使用
- 页面打开的时候,浏览器会自动给我们生成一个全局作用域window。
- 这个作用域会一直存在,直到页面关闭就销毁了
2、局部作用域
- 局部作用域就是在全局作用域下面有开辟出来的一个相对小一些的作用域。
- 在局部作用域中定义的变量只能在这个局部作用域内部使用。
- 在Js中只有函数能生成一个局部作用域,别的都不行
- 每一个函数,都是一个局部作用域
5、变量使用规则
有了作用域以后,变量就有了使用范围,也就有了使用规则
变量使用规则分为两种,访问规则 和 赋值规则
1、访问规则
当我想获取一个变量的值的时候,我们管这个行为叫做 访问
获取变量的规则:
。首先,在自己的作用域内部查找,如果有,就直接拿来使用
。如果没有,就去上一级作用域查找,如果有,就拿来使用
。如果没有,就继续去上一级作用域查找,依次类推
。如果一直到全局作用域都没有这个变量,那么就会直接报错 (该变量 is not defined)
6、对象
1、对象概念
对象是一个复杂数据类型
其实说是复杂,但是没有很复杂,只不过是存储了一些基本数据类型的一个集合
var obj = {
num: 100.
str: 'he1lo world' ,
boo: true
}
。这里的{}和函数中的{}不一样
。函数里面的是写代码的,而对象里面是写一些数据的
。对象就是一个键值对的集合
。{}里面的每一个键都是一个成员
。也就是说,我们可以把一些数据放在一个对象里面,那么他们就互不干扰了
。其实就是我们准备一个房子,把我们想要的数据放进去,然后把房子的地址给到变量名,当我们需要某一个数据的时候,就可以根据变量名里面存储的地址找到对应的房子,然后去房子里面找到对应的数据
2、 创建对象
1、创建对象的方式
。字面量的方式创建一个对象
// 创建一个空对象
var obj = [}
// 像对象中添加成员
obj.name = Jack
obj.age = 18
。内置构造函数的方式创建对象
// 创建一个空对象
var obj = new object()
// 向对象中添加成员
obj.name ='Rose
obj.age = 20
。object 是js内置给我们的构造函数,用于创建一个对象使用的
2、对象的增删改查
方式一:
3、对象的遍历
//创建对象
var obj = {
name : "xiaoming",
age : 100,
location: "laozhou"
}
//遍历对象
for(var i in obj){
//获取key
console.log(i)
//获取value
console.log(obj[i])
}
4、 数据类型之间存储的区别
。既然我们区分了基本数据类型和复杂数据类型
。那么他们之间就一定会存在一些区别
。他们最大的区别就是在存储上的区别
。我们的存储空间分成两种 栈和堆
。栈:主要存储基本数据类型的内容
。堆:主要存储复杂数据类型的内容
1、基本数据类型在内存中的存储情况
。var num= 100,在内存中的存储情况
。直接在栈空间内有存储一个数据
2、复杂数据类型在内存中的存储情况
。下面这个对象的存储
var obj = {
name: 'Jack'
age: 18,
gender:'男'
}
。复杂数据类型的存储
1.在堆里面开辟一个存储空间
2.把数据存储到存储空间内
3.把存储空间的地址赋值给栈里面的变量
7、数组
1、概念
1、什么是数组?
。字面理解就是数字的组合
。其实不太准确,准确的来说数组是一个 数据的集合
。也就是我们把一些数据放在一个盒子里面,按照顺序排好
[1, 2, 3,'he11o', true, false]
。这个东西就是一个数组,存储着一些数据的集合
2、数据类型分类
。number / string / boolean / undefined / nul1 / object / function / array /…
。数组也是数据类型中的一种
。我们简单的把所有数据类型分为两个大类 基本数据类型和 复杂数据类型
。基本数据类型: number /string / boolean /undefined /null
。复杂数据类型: object / function /array /…
2、数组的创建
1、创建一个数组
。数组就是一个[ ]
。在[ ]里面存储着各种各样的数据,按照顺序依次排好
1、字面量创建一个数组
直接使用[ ]的方式创建一个数组
//创建一个空数组
var arr1 = []
//创建一个有内容的数组
var ageArr = [1,2,3,4]
var nameArr = ["xiaoming","zhangsan"]
var studentArr =[{
name:"xiaoming",
age:100
},{
name :"zhangsan",
age : 18
}]
2、内置构造函数创建数组
使用JS的内置构造函数Array创建一个数组
//创建一个空数组
var arr1 = new Array()
//创建一个长度为10的数组
var arr2 = new Array(10)
//创建一个有内容的数组
var arr3 = new Array(1,2,3)
3、数组的长度length
length:长度的有意思
length:就是表示数组的长度,数组里面有多个成员
4、数组的操作
//查看数组的长度
var arr1 = new Array(1,2,3)
console.log(arr1.length) //输出3
//清空数组
arr1.length = 0
console.log(arr1) //输出0
//数组的读取 索引
var arr2 =["xiaoming","zhangsan","lisi"]
//获取数组的每个值
console.log(arr2[0],arr2[1],arr2[3])
//修改 将第一个改为kevin
arr2[0] = "kevin"
console.log(arr2) //["kevin","zhangsan","lisi"]
//增加一个值
arr[3] = "xinzeng"
console.log(arr2)
//数组的遍历
var arr3[1,3,5,7,9]
for(var i = 0;i<arr3.length;i++){
console.log(arr3[i])
}
//数组的复制 修改一个另一个不会改变 var arr4=arr3 修改也给另一个会改变
var arr4 = []
for(var i = 0;i<arr3.length;i++){
arr4[i] = arr3[i]
}
5、冒泡排序
1、概念
。先遍历数组,让挨着的两个进行比较,如果前一个比后一个大,那么就把两个换个位置
。数组遍历一遍以后,那么最后一个数字就是最大的那个了
。然后进行第二遍的遍历,还是按照之前的规则,第二大的数字就会跑到倒数第二的位置
。以此类推,最后就会按照顺序把数组排好了
2、案例
<script>
var arr= [7,9,5,2,3,1,4,6,8]
for(var m=0;m<arr.length-1;m++){
for(var i=0;i<arr.length-1-m;i++){
if(arr[i]>arr[i+1]){
var temp =arr[i]
arr[i]=arr[i+1]
arr[i+1]=temp
}
}
}
console.log(arr)
</script>
注意: 外层循环减一,里面在减一的基础上还要减外层的循环次数
6、选择排序
1、概念
。先假定数组中的第 0个就是最小的数字的索引
。然后遍历数组,只要有一个数字比我小,那么就替换之前记录的索引
。知道数组遍历结束后,就能找到最小的那个索引,然后让最小的索引换到第 0 个的位置
。再来第二趟遍历,假定第1 个是最小的数字的索引
。在遍历一次数组,找到比我小的那个数字的索引
。遍历结束后换个位置
2、案例
var arr1= [7,9,5,2,3,1,4,6,8]
for(var m=0;m<arr1.length-1;m++){
var minIndex = m
for(var i=m+1;i<arr1.length;i++ ){
if(arr1[i]<arr1[minIndex]){
minIndex=i
}
}
var temp1 =arr1[m]
arr1[m]=arr1[minIndex]
arr1[minIndex]=temp1
}
console.log(arr1)
7、数组的常用方法
1、概念
。数组是一个复杂数据类型,我们在操作它的时候就不能再想基本数据类型一样操作了
。比如我们想改变一个数组
// 创建一个数组
var arr = [1,2.3]
// 我们想把数组变成只有 1 和 2
arr = [1,2]
。这样肯定是不合理,因为这样不是在改变之前的数组
。相当于新弄了一个数组给到 arr 这个变量了
。相当于把 arr 里面存储的地址给换了,也就是把存储空间换掉了,而不是在之前的空间里面修改
。所以我们就需要借助一些方法,在不改变存储空间的情况下,把存储空间里面的数据改变了
2、数组常用方法
//1、push 是用来在数组的末尾加一个元素,返回值为数组的长度
var arr = [1,2,3]
var res = arr.push(4)
console.log(arr) //[1,2,3,4]
console.log("返回值:",res) //返回值是数组的长度
//2、pop 删除最后一个元素 ,返回值是删除的元素
var respop = arr.pop()
console.log(arr) //[1,2,3,4]
console.log("返回值:",respop ) //返回值是删除的元素
//3、unshift 前面追加元素 返回值是数组的长度
var resunshift = arr.unshift("teichui");
console.log(arr) //["teichui",1,2,3]
console.log("返回值:",resunshift ) //返回值是数组的长度
//4、shift 前面删除元素 返回值是删除的元素
var resshift = arr.shift()
console.log(arr) //[1,2,3]
console.log("返回值:",resshift ) //返回值是删除的元素
//5、splice 可以删除也可以增加 ,返回值是删除的元素数组
//删除 splice(从哪个下标开始删,删几个);
var ressplice =arr.splice(1,2);
console.log(arr) //[1]
console.log("返回值:",ressplice) //[2,3]
//增加 splice(从哪个下标开始删,删几个,新增的元素) 如果删除的个数为0,则表示追加到要“从哪个下标开始删”下标的后面
var ressplice =arr.splice(1,2,"xinzeng");
console.log(arr) //[1]
console.log("返回值:",ressplice) //[2,3]
//6、倒叙排序 resver
var arr2 = [1,2,3,4]
arr2.reverse()
console.log(arr2) //[4,3,2,1]
//7、sort 排序
var arr3 = [11,3,21,56,7]
arr3.sort()
console.log(arr3) //[11,21,3,56,7] 只按照第一位排序
//sort接受一个回调函数
arr3.sort(function(a,b){ //参数的命名随便起
return a-b //a-b升序 b-a 降序
})
console.log(arr3)
//不影响原数组的方法
//8、拼接 concat 返回值为拼接后的字符串
var arr1 = [1,2,3]
var arr2 = [4,5,6]
var arr3 = arr1.concat(arr2,7,[8,9]);
console.log(arr3)
var arr4 = arr1.concat();//相当于创建了新地址
//10、截取 slice 返回值为截取的数组
var arr5 = ["aaa","bbb","ccc"]
var arr6 = arr5.slice(0,2) //如果只有一个参数,表示从开始截取到最后
console.log(arr6)//['aaa', 'bbb']
var arr7 = arr5.slice()//["aaa","bbb","ccc"]
var arr8 = arr5.slice(2,-1)//长度+ 负1
//11、indexOf 从前查看元素索引
var index = arr5.indexOf("aaa")
console.log(index) //0
var index1 = arr5.indexOf("aaa",1)//表示从下标为1开始查找
//12、lastIndexOf 从后往前找 -1表示找不到
// 13、foreach 遍历
var arr = ["aaa","bbbb","cccc"]
//回调函数
arr.forEach(function(item,index){
console.log(item,index)
})
//14、map 映射
var arr = [1,2,3,4,5]
//求每个元素的平方
var arr2 = arr.map(function(item){
return item*item
})
console.log(arr2)//[1, 4, 9, 16, 25]
// 15、filter 过滤
var arr =[100,200,300]
//过滤大于200的元素
var arr2 = arr.filter(function(item){
return item>200
})
console.log(arr2)
var arr =[
{
name:"aaa",
price:100
},{
name:"bbbb",
price:200
},{
name:"cccc",
price:300
}
]
var arr2 = arr.filter(function(item){
return item.price>200
})
console.log(arr2) //{name: 'cccc', price: 300}
//16、every 每一个
var arr = [98,90,92,94]
//每一个元素都满足时为true
var arr2 = arr.every(function(item){
return item>=90
})
console.log(arr2)//true
//17、some 只要一个满足条件 就是true
var arr = [20,80,72,94]
var arr2 = arr.some(function(item){
return item>=90
})
console.log(arr2)//true
//18、find
var arr = [
{
name:"语文",
grade:90
},{
name:"英语",
grade:95
},{
name:"数学",
grade:100
}
]
var arr2 = arr.find(function(item){
return item.grade===100
})
console.log(arr2)//{name: '数学', grade: 100}
//19、reduce 叠加
var arr = [1,2,3,4,5]
var arr2 = arr.reduce(function(prev,item){
return prev+item
},0) //0表示prev的初始值为0
console.log(arr2)
//第一次:prev 0 item 1
//第二次:prev 1 item 2
//第三次:prev 3 item 3
//prev是return返回的结果
8、数组去重
//方法一:
var arr = [1,2,3,4,4,3,2,1]
var arr1 =[]
for(var i=0;i<arr.length;i++){
if(arr1.indexOf(arr[i])=== -1){
arr1.push(arr[i])
}
}
console.log(arr1)
//方法二 :利用对象
var obj = {}
for(var i=0;i<arr.length;i++){
obj[arr[i]]=""
}
console.log(obj) //{1: '', 2: '', 3: '', 4: ''}
var arr2 =[]
for(var i in obj){
arr2.push(Number(i))
}
console.log(arr2)// [1, 2, 3, 4]
8、字符串
1、 创建字符串
。我们创建字符串也分为两种方法 字面量和构造函数
1、字面量:
var str = 'he1lo'
2、构造函数创建
var str = new string('he11o')
2、字符集
ASCIl 字符集
。我们都知道,计算机只能存储 0101010 这样的二进制数字
。那么我们的az/AZ/s/@/…之类的内容也有由二进制数字组成的
。我们可以简单的理解为az/AZ/s/@/…之类的内容都有一个自己的编号,然后在计算机存储的时候,是存储的这些编号,我们看的时候,也是通过这些编号在解析成我们要看到的内容给我们看到
3、统计字符出现的次数
//统计字符出现的次数
var str ="abcabcab"
var obj ={}
for(var i=0;i<str.length;i++){
console.log(str[i])
var key = str[i]
/* if(obj[key]===undefined){
obj[key]=1
}else{
obj[key]++
} */
//或
if(obj[key]){
obj[key]++
}else{
obj[key]=1
}
}
console.log(obj)
4、字符串常用方法
//1、chartAt(索引) 返回索引对应的字符
var str ="kerwin"
var str1=str.charAt(0)
console.log(str1) //k
//2、charCodeAt(索引) 返回索引对应的字符编码
var str ="kerwin"
var str1 = str.charCodeAt(0)
console.log(str1)
//String.fromCharCode(字符编码) 将字符编码转换为字母
String.fromCharCode(91)
//3、toUpperCase、toLowerCase 转换大小写
str.toUpperCase()//转换为大写
str.toLowerCase()//转换为小写
//4、截取 substr(开始索引,长度) subString(开始索引,结束索引) slice(开始索引,结束索引)
var str ="kerwin"
var str1 =str.substr(0,2)
console.log(str1) //ke
var str2 = str.substring(1,2) //只有一个参数表示直到截取完
console.log(str2)//e
var str3 = str.slice(1,2)
console.log(str3)//e
//5、replace(要替换的字符,替换为的字符) 替换 注意只能替换遇到的第一个
var str ="abdwadwa"
var str1 = str.replace("a","*")
console.log(str1)
//6、分割 split 将字符转换为数组
var str = "a,b,c,d"
console.log(str.split(","))//['a', 'b', 'c', 'd']
//7、trim 去掉首尾空格
// trimStart() trimLeft() 去掉首空格
//trimEnd() trimRight() 去掉尾空格
//8、indexOf(查找的元素,从哪个索引开始查找) lastIndexOf(查找的元素,从哪个索引开始查找) 查找元素所在的索引
//9、concat连接字符串
5、模糊查询
//模糊查询
var arr =["aaa","abc","bcc","bcd","ddd"]
//数组的filter 字符串的indexOf
var input = prompt("请输入查询的内容")
var res = arr.filter(function(item){
return item.indexOf(input)>-1
})
console.log(res) // ['abc', 'bcc', 'bcd']
6、JSON格式字符串
//JSON格式的字符串 JSON.parse(str)字符串转换为对象
var str='{"name":"kewen","age":100}'
console.log(str)
var obj = JSON.parse(str)
//将对象转换为JSON字符串
var str2 = JSON.stringify(obj)
7、模板字符串
//原生的如果字符串要换行,必须加\,否则报错
var myhtml ='<li>1111</li>\
<li>2222</li>\
<li>2222</li>'
document.write(myhtml)
//es6 --``(反引号)
var myes6html =`<li>1111</li>
<li>2222</li>
<li>2222</li>`
document.write(myes6html)
//模板字符串也可以拼接变量
var myname="kerwin"
var str = `my name is ${myname}`
document.write(str)
9、数字常用方法
//1、toFixed(要保留小数的位数) 保留小数位数 返回值为字符串
var price =123.45678
//保留两位小数
console.log(price.toFixed(2)) //123.45
//2、Math对象
//1、随机数 random 返回0-1的随机数,包含0,不包含1
console.log(Math.random())
//2、round 四舍五入取整
console.log(Math.round(4.46))//4
//3、ceil()向上取整 floor() 向下取整
console.log(Math.ceil(4.46))//5
console.log(Math.floor(4.46))//4
//4、abs绝对值
console.log(Math.abs(-10))//10
//5、sqrt 平方跟
console.log(Math.sqrt(25))//5
//6、pow(底数,指数)
console.log(Math.pow(3,3))//27
//7、Max(多个参数) 取最大值 min(多个参数) 取最小值
//8、PI(圆周率 Π)
console.log(Math.PI)//3.141592653589793
随机数
10、时间对象 Date
1、概念及创建
。js提供的内置构造函数,专门用来获取时间的
1、new Date()
。new Date(在不传递参数的情况下是默认返回当前时间
var time = new Date()
console.log(time) // 当前时间 Fri Mar 01 2019 13:11:23 GMT+800 (中国标准时间)
。new Date()在传入参数的时候,可以获取到一个你传递进去的时间
var time = new Date('2019-03-03 13:11:11')
console.log(time) // sun Mar 03 2019 13:11:11 GMT+0800 (中国标准时间)
。new Date( )传递的参数有多种情况
1.传递一个参数 毫秒数
var date1=new Date(1000);
console.log(date1)//1970 1 1 00:00:1
2.传递两个数字,第一个表示年,第二个表示月份
var time = new Date(2019,00) // 月份从 0 开始计数,0 表示 1月,11 表示 12月
console.1og(time) // Tue Jan 01 2019 00:00:00 GMT+0800 (中国标准时间)
3.传递三个数字,前两个不变,第三个表示该月份的第几天,从 1到 31
var time = new Date(2019,00,2)
2、时间对象常用方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
var date =new Date();
console.log(date)
//获取年 2022
console.log(date.getYear());
//获取月 0-11
console.log(date.getMonth());
//获取天 (号数)
console.log(date.getDate());
//获取星期 周日0
console.log(date.getDay());
//获取时
console.log(date.getHours());
//获取分
console.log(date.getMinutes());
//获取秒
console.log(date.getSeconds());
//获取毫秒
console.log(date.getMilliseconds());
//获取时间戳 距离1970年的毫秒数
console.log(date.getTime());
//设置时间,月时分秒都一样,不能设置日,因为时自动推算周几,不能强制设置
date.setFullYear(2025);
</script>
</body>
</html>
3、定时器
。在js 里面,有两种定时器,倒计时定时器和 间隔定时器
1 倒计时定时器
。倒计时多少时间以后执行函数
。语法: setTimeout(要执行的函数,多长时间以后执行)
。会在你设定的时间以后,执行函数
var timerId = setTimeout(function () {
console.og(我执行了')
,1000)
console.log(timerId) // 1
。时间是按照毫秒进行计算的,1000 毫秒就是 1秒钟
。所以会在页面打开 1 秒钟以后执行函数
。只执行一次,就不在执行了
。返回值是,当前这个定时器是页面中的第几个定时器
2、间隔定时器
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
//延时定时器 返回值为:定时器注册的顺序
var time1 = setTimeout(function(){
console.log("--------")
},1000)
//间隔定时器 setInterval 返回值为:定时器注册的顺序
var time2 = setInterval(function(){
console.log("每个几秒执行一次")
},1000)
//清除延时定时器
clearTimeout(time1)
//清除间隔定时器
clearInterval(time2)
</script>
</body>
</html>
三、BOM
1、概念
。BOM(Browser object Mode1): 浏览器对象模型
。其实就是操作浏览器的一些能力
。我们可以操作哪些内容
- 获取一些浏览器的相关信息(窗口的大小)
- 操作浏览器进行页面跳转
- 获取当前浏览器地址栏的信息
- 操作浏览器的滚动条
- 浏览器的信息(浏览器的版本)
- 让浏览器出现一个弹出框(alert /confirm /prompt )
。BOM 的核心就是window 对象
。window 是浏览器内置的一个对象,里面包含着操作浏览器的方法
2、方法
1.获取浏览器窗口的尺寸
。innerHeight和innerwidth
这两个方法分别时用来获取浏览器窗口的宽度和高度(包含滚动条的)
<body>
<style>
//清除原有样式
*{
margin: 0;
padding: 0;
}
</style>
<script>
console.log(window.innerWidth)
console.log(window.innerHeight)
</script>
</body>
2、浏览器的弹出层
//弹出层
window.alert("弹出层");
//询问框 返回值为true或flase
var res = confirm("你确定删除吗?")
//输入框 prompt 返回值为输入的内容
var res1 = prompt("请输入用户名")
3、浏览器的地址信息
。在window 中有一个对象叫做 location
。就是专门用来存储浏览器的地址栏内的信息的
location.href
。location.href 这个属性存储的是浏览器地址栏内 url 地址的信息
conso1e.1og(window.1ocation.href)
。会把中文变成urT 编码的格式
。location.href 这个属性也可以给他赋值
window.location.href = './index.htm'
decodeURI()//可以解码地址栏的中文转换字符
//这个就会跳转页面到后面你给的那个地址
location.reload
location.reload()这个方法会重新加载一遍页面,就相当于刷新是一个道理
4、浏览器的常见事件
1、浏览器的 onload 事件
。这个不在是对象了,而是一个事件
。是在页面所有资源加载完毕后执行的
window.onload = function(){
//页面所有的资源都加载完毕后执行(图片,视频,dom)
console.1og("页面已经加载完毕')
}
//resize //窗口改变大小时触发,可用于改变窗口大小时改变页面布局
window.onresize=function(){
console.log("-------")
}
window.onscroll =function(){
console.log("滚动条滚动时触发")
}
2、浏览器滚动距离
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<style>
body{
height: 3000px;
}
</style>
<script>
window.onscroll = function(){
//获取滚动离上面的距离 scrollTop(a,b) 参数表示滚动的距离
//document.documentElement.scrollTop 必须要有<!DOCTYPE html> 才生效
//<!DOCTYPE html>没有用document.body.scrollTop;
//兼容性
console.log(document.documentElement.scrollTop||document.body.scrollTop)
//赋值
//1、参数方式
window.scrollTop(0,0)
//2、对象方式
window.scrollTo({
left:0,
top:0
})
}
</script>
</body>
</html>
5、浏览器打开标签页
语法:window.方法名
方法:
open():打开一个新的窗口
close():关闭浏览器窗口
scrollBy():按照指定的像素来滚动内容
scrollTo():把内容滚动到指定的坐标
blur():把键盘焦点从顶层窗口移开
focus():把键盘焦点给予一个窗口
print():打印当前窗口的内容
6、浏览器的历史记录
。window 中有一个对象叫做 history
。是专门用来存储历史记录信息的
history.back
。history.back 是用来会退历史记录的,就是回到前一个页面,就相当于浏览器上的后退 按钮
window.history.back()
window. history.go(-1)
。前提是你要有上一条记录,不然就是一直在这个页面,也不会回退
history.forword
。history.forword 是去到下一个历史记录里面,也就是去到下一个页面,就相当于浏览器上的前进按钮
window. history.forward()
window. history.go(1) //参数表示前进几个页面
。前提是你要之前有过回退操作,不然的话你现在就是最后一个页面,没有下一个
式(O) 视图WE20考助(H)
7、本地存储
1、localstorage (永久存储)
//增
localstorage.setitem("name","kerwin")
//注意:只能存字符串,不能存对象、数组等只能用JSON.stringify()转换成字符串
localstorage.setItem("obj",JsON.stringify({name:"kerwin"age:100}))
//取
loca1storage.getitem("name")
//后面要用的话用JSON.parse()转换成对象用
JSON.parse(localstorage.getItem("obj")))
//删
loca1storage.removeItem("name")
//清空
loca1storage.clear()
2、sessionStorage(会话存储 关闭页面丢失)
//增
sessionstorage.setitem("name","kerwin")
//取
sessionstorage.getitem("name")
/删
sessionstorage.removeitem("name")
//清空
sessionstorage.clear()
记住密码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div>
用户名:
<input type="text" id="username"/>
</div>
<div>
密码:
<input type="password" id="password" />
</div>
<div>
<button id="login">登录</button>
</div>
<script>
//先获取用户名密码信息进行存储
var uservalue = localStorage.getItem("username")
var passvalue = localStorage.getItem("password")
if(uservalue && passvalue){
username.value=uservalue
password.value=passvalue
}
login.onclick = function(){
//获取输入的内容
console.log(username.value,password.value)
var res = confirm("是否记住密码?")
if(res){
//将内容存储到本地
localStorage.setItem("username",username.value)
localStorage.setItem("password",password.value)
}
}
</script>
</body>
</html>
四、DOM
1、概念
。DOM(Document object Mode1): 文档对象模型
。其实就是操作 html 中的标签的一些能力
我们可以操作哪些内容
- 获取一个元素
- 移除一个元素
- 创建一个元素
- 向页面里面添加一个元素
- 给元素绑定一些事件
- 获取元素的属性
- 给元素添加一些css样式
。DOM 的核心对象就是 docuemnt 对象
。document 对象是浏览器内置的一个对象,里面存储着专门用来操作元素的各种方法。
。DOM: 页面中的标签,我们通过s 获取到以后,就把这个对象叫做 DOM 对象
2、方法
1、获取一个元素
。通过JS代码来获取页面中的标签
。获取到以后我们就可以操作这些标签了
1、getElementByld
getElementById 是通过标签的 id 名称来获取标签的。因为在一个页面中 id 是唯一的,所以获取到的就是一个元素
<body>
<div id="box"></div>
<script>
var box = document.getElementById('box')console.log(box) // <div></div>
</script>
</body>
。获取到的就是页面中的那个id 为 box 的 div 标签
/*
html、head、body非常规
常规:id、class、tag.....
*/
console.log(document.documentElement) //获取html
console.log(document.head)//获取head
console.log(document.body)//获取baody
// 获取元素的方式
// 根据 id 获取页面元素
// var ele = document.getElementById( 'abc' )
// 输出返回值
// console.log(ele)
// 根据类名获取页面元素
// var eles = document.getElementsByClassName( 'box' )
// 输出返回值
// console.log( eles )
//根据name属性获取页面元素
//var elss =document.getElementsByName("username")
// 根据标签名获取页面元素
// var eles = document.getElementsByTagName( 'div' )
// 输出返回值
// console.log( eles )
// 根据选择器获取一个
// var ele = document.querySelector( '.box' )
// 输出返回值
// console.log( ele )
// 根据选择器获取一组
var eles = document.querySelectorAll( '.abc' )
// 输出返回值
console.log( eles )
2、操作元素属性
<body>
<button>操作属性</button>
<div id="box" hello="world">div 标签</div>
<script>
// 操作元素属性
// 原生属性:标签自带的属性 如:text name password等
// 获取元素
var box = document.querySelector( 'div' )
var inp = document.querySelector( 'input' )
var btn = document.querySelector( 'button' )
// // 获取元素属性
// console.log( box.id )
// console.log( inp.type )
// // 给按钮绑定点击事件
// btn.onclick = function () {
// // 修改元素属性
// box.id = 'content'
// inp.type = 'checkbox'
// }
// 获取自定义属性
var res = box.getAttribute( 'hello')
console.log( res )
// 修改自定义属性
box.removeAttribute( 'hello', '新来的')
//h5 约定加data_****
//获取自定义属性
console.log(box.dataset)
//添加自定义属性
box.dataset.xiaoming="hello3"
//<div id="box" hello="world" data-xiaoming="hello3">div 标签</div>
</script>
</body>
3、操作元素内容
innerHTML和innerText的语法结构:标识符.innerHtml/innerText=“值”
区别: innerHtm含子标签(可以解析HTML标签) innerText不含子标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button>操作内容</button>
<div>
<p>文本内容</p>
</div>
<script>
// 操作元素文本内容
// 获取元素
// var ele = document.querySelector( 'div' )
// var btn = document.querySelector( 'button' )
// // 获取元素的文本内容
// console.log( ele.innerText )
// // 给 按钮 绑定点击事件
// btn.onclick = function () {
// // 设置 div 内的文本内容
// ele.innerText = '新内容'
// }
// 获取元素
var ele = document.querySelector( 'div' )
var btn = document.querySelector( 'button' )
// 获取元素的文本内容
console.log( ele.innerHTML )
// 给 按钮 绑定点击事件
btn.onclick = function () {
// 设置 div 内的文本内容
ele.innerHTML = '<span>新内容</span>'
}
</script>
</body>
</html>
4、操作元素样式
<script>
// 操作元素类名
// 获取元素
var box = document.querySelector( 'div' )
var btn = document.querySelector( 'button' )
// 获取行内样式 style只能访问行内样式
console.log( box.style.width )
console.log( box.style.height )
console.log( box.style.backgroundColor )
console.log( box.style["background-color"] )//方式二
// 设置 div 的行内样式
box.style.width = '200px'
box.style.height = '300px'
box.style.backgroundColor = 'skyblue'
// 获取元素
var box = document.querySelector( 'div' )
var btn = document.querySelector( 'button' )
// 可以获取内部样式、外部样式、行内样式 getComputedStyle 但是只能获取,不能赋值写样式
console.log( window.getComputedStyle(box).width )
console.log( window.getComputedStyle(box).height )
console.log( window.getComputedStyle(box).fontSize )
</script>
5、操作元素类名
1、简单选项卡
// 获取元素
var box = document.querySelector( 'div' )
var btn = document.querySelector( 'button' )
// className 设置 div 内的类名
box.className = '新内容'
//classList属性 获取所有的Class名字
console.log(box.classList)
//增加 可以自动去重
box.classList.add("item2")
//删除class
box.classList.remove("item2")
//切换 toggle 如果有删除,没有加上
box.classList.toggle("item")
2、完整选项卡
案例:密码可见
案例:全选
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 100px;
padding: 20px;
border: 1px solid pink;
margin: 30px auto;
border-radius: 5px;
}
hr {
margin: 10px 0;
}
</style>
</head>
<body>
<div class="box">
全选 : <input type="checkbox"> <br>
<hr>
<input type="checkbox"> 选项一 <br>
<input type="checkbox"> 选项二 <br>
<input type="checkbox"> 选项三 <br>
<input type="checkbox"> 选项四 <br>
</div>
<script>
// 1. 获取元素
var allBtn = document.querySelector('input')
var items = document.querySelectorAll('input:nth-child(n + 2)')
// 2. 给全选按钮绑定事件
allBtn.onclick = function () {
// 2-1. 拿到自己的选中状态
var type = allBtn.checked
// 2-2. 把自己的选中状态设置给每一个选项按钮
for (var i = 0; i < items.length; i++) {
items[i].checked = type
}
}
// 3. 循环给每一个选项按钮绑定点击事件
for (var i = 0; i < items.length; i++) {
// 3-1. 给每一个选项按钮绑定点击事件
items[i].onclick = function () {
// 3-2. 首先定义假设变量, 假设所有按钮都是选中的
var flag = true
// 3-3. 通过循环来验证我们的假设
for (var j = 0; j < items.length; j++) {
if (items[j].checked === false) {
flag = false
break
}
}
// 3-4. 把我们得到的结果设置给全选按钮
allBtn.checked = flag
}
}
</script>
</body>
</html>
案例:选项卡
3、DOM节点
。DOM 的节点我们一般分为常用的三大类元素节点/文本节点/属性节点
。什么是分类,比如我们在获取元素的时候,通过各种方法获取到的我们叫做元素节点(标签节点)
。比如我们标签里面写的文字,那么就是文本节点
。写在每一个标签上的属性,就是属性节点
1 元素节点
。我们通过 getElementBy…获取到的都是元素节点
2 属性节点
。我们通过getattribute 获取的就是元素的属性节点
3 本节点
。我们通过innerText 获取到的就是元素的文本节点
4、获取节点的方式
<body>
<div>helle</div>111
<div id="box" index="1">
kerwin
<p>1111</p>
<!-- 注释 -->
</div>
<div>888</div>
<script>
//1、childNodes 获取某一个节点的所有子节点
console.log(box.childNodes)
// 2、children 获取所有的元素(标签)节点
console.log(box.children)
// firstChild 获取第一个节点
//firstElementChild 获取第一个元素的节点
console.log(box.firstChild)
console.log(box.firstElementChild)
//previousSibling 获取上一个兄弟节点
console.log(box.previousSibling)
//previousElementSibling 获取上一个元素的兄弟节点
console.log(box.previousElementSibling)
//nextSibling 获取下一个兄弟节点
console.log(box.nextSibling)
//nextElementSibling 获取下一个元素的兄弟节点
console.log(box.nextElementSibling)
//parentNode 获取父级的节点
console.log(box.parentNode)
//parentElement 获取父级节点,必须是元素节点
console.log(box.parentElement)
//获取所有的属性节点
console.log(box.attributes)
</script>
</body>
5、操作DOM 节点
。我们所说的操作无非就是 增删改查 (CRUD)
。创建一个节点(因为向页面中增加之前,我们需要先创建一个节点出来)
。向页面中增加一个节点
。删除页面中的某一个节点
。修改页面中的某一个节点
。获取页面中的某一个节点
<body>
<div id="box">
<div id="child">11111</div>
</div>
<script>
//创建元素节点
var res=document.createElement("div")
res.innerHTML="新创建的节点"
res.style.background="yellow"//可以添加属性
console.log(res)//<div>新创建的节点</div>
//插入节点 appendChild(要插入的节点)
box.appendChild(res)
//在节点之前插入insertBefore(要插入的节点)
box.insertBefore(res,child)
//删除节点remove(节点对象)
box.remove(child)
//删除自己及后代
box.remove();
//替换节点replaceChild(新的节点,老的节点)
var odiv=document.createElement();
odiv.innerHTML="2222"
box.replaceChild(odiv,child);
//克隆节点 cloneNode(参数) false不克隆后代,true克隆后代,不传参数默认为false
var str = box.cloneNode()
document.body.appendChild(str)
</script>
</body>
6、节点属性
<script>
// 先获取 u1
var ou1 = document . queryselector('u1 ')
// 获取到 u] 下的第一个子元素节点,是一个元素节点
var eleNode = ou1.firstElementChild
// 获取到 u] 的属性节点组合,因为是个组合,我们要拿到节点的话要用索引
var attrNode = ou1.attributes[O]
// 获取到 u] 下的第一个子节点,是一个文本节点
var textNode = oul.firstchild
</script>
1、nodeType
。nodeType:获取节点的节点类型,用数字表示
console.1og(eleNode.nodeType) // 1
console.1og(attrNode .nodeType) // 2
console.1og(textNode.nodeType) // 3
。nodeType === 1就表示该节点是一个元素节点
。nodeType === 2就表示该节点是一个属性节点
。nodeType === 3就表示该节点是一个注释节点
2、nodeName
。nodeName:获取节点的节点名称
console.log(eTeNode.nodeName) // LI
console.log(attrNode.nodeName) // test
console.log(textNode.nodeName) // #text
。元素节点的nodeName 就是 大写标签名
。 属性节点的 nodeName 就是 属性名
。文本节点的 nodeName 都是 #text
3、nodeValue
。nodevalue: 获取节点的值
console.og(eleNode.nodevalue) // null
console.og(attrNode.nodevalue) // 我是 u 的一个属性
console.1og(textNode.nodevalue) // 换行 + 空格
。无素节点没有 nodevalue
。属性节点的 nodevalue 就是 属性值
。文本节点的 nodevalue 就是 文本内容
7、获取元素尺寸
。就是获取元素的“占地面积"
offsetWith 和 offsetHeight
。offsetwidth : 获取的是元素内容+padding +border 的宽度。
。offsetHeight : 获取的是元素内容+padding + border 的高度
clientWidth 和 clientHeight
。clientwidth: 获取的是元素内容+padding 的宽度。
。clientHeight : 获取的是元素内容+padding 的高度
注意
。获取到的尺寸是没有单位的数字
。当元素在页面中不占位置的时候,获取到的是0
。单位 数字
。box-sizing: 计算没影响
。display:none 拿不到任何值
<script>
console.log(box.offsetWidth)
console.log(box.offsetHeight)
/*
注意:
1、单位 数字
2、box-sizing: 计算没影响
3、display:none 拿不到任何值
*/
console.log(box.clientWidth)
console.log(box.clientHeight)
</script>
8、获取元素偏移量
//获取div距离左、上的距离
//参考点为到定位父级的边界 加了position:relative
//如果父级元素都没有定位,则已body节点为边界
console.log(box.offsetLeft,box.offsetTop)
//获取边框的宽度
console.log(box.clientLeft,box.clientHeight)
9、获取可视窗口的尺寸
//算滚动条的宽度
console.log(innerHeight)
console.log(innerWidth)
//不算滚动条的宽度
console.log(document.documentElement.clientHeight)
console.log(document.documentElement.clientWidth)
案例、懒加载
五、事件
1、事件的绑定与解绑
<body>
<div id="box">aaa</div>
<div id="box2">bbbb</div>
<script>
//绑定多个事件处理函数,后面回覆盖前面的
boc.onclick=function(){
console.log("22220")
}
//绑定多个事件处理函数,会安装顺序执行,不会覆盖
box2.addEventListener("click",functin(){
console.log("3333")
//事件解绑
this.onclick =null
})
</script>
</body>
2、常见的事件
。我们在写页面的时候经常用到的一些事件
。大致分为几类,浏览器事件/鼠标事件/键盘事件/表单事件/触摸事件
1、浏览器事件
load : 页面全部资源加载完毕0
scroll:浏览器落动的时候触发
2、鼠标事件
。click:点击事件
。dblclick:双击事件
。contextmenu:右键单击事件
。mousedown : 鼠标左键按下事件.
。mouseup:鼠标左键抬起事件
。mousemove:鼠标移动
//父框和子框都触发
onmouseover()//移入
onmouseout()//移出
//只有父框才触发
onmouseenter()//移入
onmouseleave()//移出
3、键盘事件
keyup :键盘抬起事件
keydown :键盘按下事件
keypress :键盘按下再抬起事件
4、表单事件
。change:表单内容改变事件
。input:表单内容输入事件,类似与百度
。submit:表单提交事件,return false 可以阻止提交
。focus:获取焦点
。blur:失去焦点
5、触摸事件
touchstart :触摸开始事件
touchend:触摸结束事件
touchmove :触摸移动事件
touchcancel:当触摸屏幕时来电话触发;
6、事件对象
1、概念
。什么是事件对象?
。就是当你触发了一个事件以后,对该事件的一些描述信息
例:
。你触发一个点击事件的时候,你点在哪个位置了,坐标是多少
。你触发一个键盘事件的时候,你按的是哪个按钮
。每一个事件都会有一个对应的对象来描述这些信息,我们就把这个对象叫做 事件对象
。浏览器给了我们一个黑盒子,叫做 window.event,就是对事件信息的所有描述。
- 比如点击事件
- 你点在了 0,0位置,那么你得到的这个事件对象里面对应的就会有这个点位的属性
- 你点在了 10,10位置,那么你得到的这个事件对象里面对应的就会有这个点位的属性
box.onclick = function(evt){
evt=evt||window.event//兼容 ie 678 使用window.event
console.log(evt)
}
oDiv.onclick = function(){
console.1og(window.event.x轴坐标点信息)
console.1og(window.event.Y轴坐标点信息)
}
2、事件对象—鼠标对象
box.onclick = function(e){
//clientX clientY 距离浏览器可视窗口的左上角的坐标值
console.log(e.clientX,e.clientY)
//pageX pageY 距离页面(文档流)的左上角的坐标
console.log(e.pageX,e.pageY)
//offsetX offsetY 距离触发盒子左上角的位置
console.log(e.offsetX,e.offsetY)
}
3、鼠标跟随
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
img {
width: 50px;
height: 50px;
position: fixed;
left: 0;
top: 0;
}
</style>
</head>
<body>
<img src="./a.png" alt="">
<script>
var imgBox = document.querySelector('img')
// 给 document 绑定一个鼠标移动事件
document.onmousemove = function (e) {
// 拿到光标相对于窗口的坐标点位
var x = e.clientX
var y = e.clientY
// 把 x 和 y 的值赋值给 img 标签的 left 和 top 样式
imgBox.style.left = x + 5 + 'px'
imgBox.style.top = y + 5 + 'px'
}
</script>
</body>
</html>
4、事件的传播
当元素触发一个事件的时候,其父元素也会触发相同的事件,父元素的父元素也会触发相同的事件
。就像上面的图片一样
。点击在红色盒子上的时候,会触发红色盒子的点击事件
。也是点击在了粉色的盒子上,也会触发粉色盒子的点击事件
。也是点击在了 body 上,也会触发 body 的点击事件
。也是点击在了 html 上,也会触发 html 的点击事件
1、阻止事件传播
可以使用:
pointer-events:none解决
//阻止事件传播
e.stopPropagation()
//ie 阻止事件传播
e.cancelBubble=true
2、阻止默认行为
// return false 阻止默认行为
document.oncontextmenu=function(){
console.log("邮件单击,自定义右键菜单")
return false
}
//evt.preventDefault()阻止默认行为
document.addEventListener("contextment",function(evt){
console.log("邮件单击,自定义右键菜单")
evt.preventDefault=false
})
3、案例:自定义右键菜单
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
ul{
list-style: none;
width: 12.5rem;
padding: 10px;
border: 1px solid black;
display: none;
}
ul li:hover{
background:skyblue;
}
</style>
<body>
<ul id="list">
<li>111</li>
<li>222</li>
<li>333</li>
</ul>
<script>
//右键创建自定义菜单
document.addEventListener("contextmenu",function(evt){
evt.preventDefault()
list.style.display = "block"
var x = evt.clientX
var y = evt.clientY
if(x >= document.documentElement.clientwidth-list.offsetWidth)
x = document.documentElement.clientwidth-list.offsetwidth
if(y >= document.documentElement.clientHeight-list.offsetHeight)
y = document.documentElement.clientHeight-list.offsetHeight
list.style.left = x + "px"
list.style.top = y + "px"
})
//点击消失自定义菜单
document.addEventListener("",()=>{
list.style.display="none"
})
list.onclick=function(){
console.log("点击的是:",evt.target || evt.srcElement)
}
</script>
</body>
</html>
4、事件委托
。就是把我要做的事情委托给别人来做
。因为我们的冒泡机制,点击子元素的时候,也会同步触发父元素的相同事件
。所以我们就可以把子元素的事件委托给父元素来做
target
。target 这个属性是事件对象里面的属性,表示你点击的目标
。当你触发点击事件的时候,你点击在哪个元素上,target 就是哪个元素
。这个 target 也不兼容,在IE 下要使用 srcElement
<body>
<u1>
<1i>1</1i>
<li>2</1i>
<1i>3</1i>
</u1>
<script>
var ou1 = docuemnt.querySelector('u1')
ou1.addEventListener('click',function (e) {
e = e l window.event
var target = e.target || e.srcElement
console.1og(target)
})
</script>
</body>
。上面的代码,当你点击ul的时候,target就是ul
。当你点击在li上面的时候,target就是li
六、this
谁调用我,this就指向谁(es6箭头函数)
1、this的指向
改变this指向的三个方法:call apply bind
<script>
//改变this指向的三个方法:call apply bind
var obj1 ={
name:"obj1",
getName:function(){
console.log("getName1",this.name)
}
}
var obj2 ={
name:"obj2",
getName:function(){
console.log("getName2",this.name)
}
}
//call(要指向的方法),执行函数,并改变this执行为函数的第一个参数
obj1.getName.call(obj2)
//call支持多个参数
obj1.getName.call(obj2,1,2,3)
//apply(要指向的方法),执行函数,并改变this执行为函数的第一个参数
obj1.getName.apply(obj2)
//直接收两个参数,第二个参数是一个数组
obj1.getName.apply(obj2,[1,2,3])
//bind 改变this指向为函数的第一个参数,不会自动执行函数
//也支持多个参数
var fun1 = obj1.getName.bind(obj2)
//调用才执行
console.log(fun1)
</script>
七、ES6
1、概念
。我们所说的 ESS 和 ES6 其实就是在js 语法的发展过程中的一个版本而已
。ECMAScript 就是js的语法
- 以前的版本没有某些功能
- 在 ES5 这个版本的时增加了一些功能
- 在ES6 这个版本的时增加了一些功能
。因为浏览器是浏览器厂高生产的 - ECMASript 发布了新的功能以唇,浏览厂商需要让自己的浏览器支持这些功能
- 这个过程是需要时间的
- 所以到现在,基本上大部分浏览器都可以比较完兽的支持了
- 只不过有丝浏览馨还是不全部支持
- 这就出现了兼容性问题
- 所以我们写代码的时就委考虑哪些方法是 ES5 或者 ES6 的,看看是不是浏筑器都支持
let 和 const 关随字
。我们以前都是使用 var 关键字来声明变量的
。在 ES6 的时候,多了两个关键字 1et 和 const,也是用来声明变量的
。只不过和 var 有一些区别 - 1、let 和 const 不允许重复声明交量
- 2、必须先定义后使用
- 3、块级作用域
let和const的区别
let:定义变量
const:定义常量
2、ES6的箭头函数
伪数组:就是像数组的形式
箭头函数的特点
1、()可以省略,前提是只有一个参数
2、{}可以省略 只有一句代码的时候或只有返回值
3、没有arguments
4、箭头函数this是父级作用域的,
<script>
//普通写法
var test1 = function(){
console.log("11111")
}
//箭头函数
var test2 = ()=>{
console.log("2222")
}
//箭头函数、()可以省略,前提是只有一个参数
var test3 =a =>{
console.log("2222",a)
}
//{}可以省略 只有一句代码的时候或只有返回值
var test4 = a =>100*a
console.log(test4(10))
/*
箭头函数的特点
1、()可以省略,前提是只有一个参数
2、{}可以省略 只有一句代码的时候或只有返回值
3、没有arguments
4、箭头函数this是父级作用域的,
*/
</script>
3、函数的默认参数,如果不穿参数,则执行默认值
//函数的默认参数,如果不穿参数,则执行默认值
function test(a=1,b=2){
return a+b
}
4、ES6的结构赋值
结构赋值: 快速的从对象和数组中获取里面的成员
//结构赋值:快速的从对象和数组中获取里面的成员
//数组
var arr =["111","222","333"]
let[x,y,z]=arr
console.log(x,y,z)
//对象
var obj ={
name:"name",
age:100,
location:"admin"
}
//因为location windows有,所以要用location:mylocation重命名来接收
let{name,age,location:mylocation}=obj
console.log(name)
console.log(age)
console.log(mylocation)
5、ES6的对象简写
mybtn.onclick = function () {
Let username = myusername.value
Let password = mypassword.value
console.log(username,password)
var obj = {
//如果key和变量名以一样,就可以省略如:
//username:username
//password:password,
//可以简写为
username
password
}
console.log(”发给后端的结构",obj)
}
6、ES6展开运算符
八、面向对象
1、概念
。首先,我们要明确,面向对象不是语法,是一个思想,是一种 编程模式
。面向: 面(脸) ,向(朝着)
。面向过程: 脸朝着过程 》 关注着过程的编程模式
。面向对象: 脸朝着对象 =》 关注着对象的编程模式
。实现一个效果
- 在面向过程的时候,我们要关注每一个元素,每一个元素之间的关系,顺序,。。
- 在面向过程的时候,我们要关注的就是找到一个对象来帮我做这个事情,我等待结果
。我们以前的编程思想是,每一个功能,都按照需求一步一步的逐步完成
2、创建对象的方式
。因为面向对象就是一个找到对象的过程
。所以我们先要了解如何创建一个对象
<script>
//字面量
var obj1={
name:"2111",
material:["111","222","333"],
setCook(){
console.log("2222")
}
}
//内置构造函数
var obj2 = new Object()
obj2.name="1111"
obj2.setCook=function(){console.log("----------")}
console.log(obj2)
//工厂函数
function createObj(name){
var obj={}
obj.name=name,
obj.material=[]
return obj
}
console.log(createObj("1111"))
//自定义构造函数 new后会自动创建一个对象
function createObj1(name){
this.name=name
this.material=[]
this.cook=function(){
console.log("=======")
}
}
var obj1 = new createObj1("22222")
console.log(obj1)
</script>
3、调用系统内置的构造函数创建对象
。 js给我们内置了一个 Object 构造函数
。这个构造函数就是用来创造对象的
//工厂函数
function createObj(name){
var obj={}
obj.name=name,
obj.material=[]
return obj
}
console.log(createObj("1111"))
//自定义构造函数 new后会自动创建一个对象
function createObj1(name){
this.name=name
this.material=[]
this.cook=function(){
console.log("=======")
}
}
var obj1 = new createObj1("22222")
console.log(obj1)
4、构造函数注意的事项
1、首字母大写
2、构造函数不写return
3、构造函数能当成普通函数用
5、面向对象的原型
function CreateObj(name){
this.name=name
}
//原型
createObj.prototype.say=function(){
console.log(this.name,"helll")
}
九、前后端交互
1、AJAX
ajax :async javascript and xml
。也就是我们客户端给服务谈发送消息的工具,以及接受响应的工具
。是一个 默认异步 执行机划的功能
AJAX的优势
1.不需要播件的支持,原生 就可以使用
2.用户体验好(不需委剧新页面就可以更新数据)
3.减轻服务端和带宽的负报
4.缺点: 搜索引擎的支持度不够,因为数据都不在灭面上,搜索引繁授索不到
AJAX 的使用
。在js 中有内置的构造函来创建 ajax 对象
。创建 ajax 对象以后,我们就使用 ajax 对象的方法去发送请求和接受响应
2、创建一个 ajax 对象
<script>
//1、创建XHR
var xhr = new XMLHttpRequest()
//2、配置open(请求方式,请求地址,是否异步)
//true 表示异步请求,一个数据没执行完,后面的可以执行(一块吃饭)
//false 表示同步请求,必须等一个数据回来后再执行后面的(一个吃完一个再吃)
xhr.open("GET","http://localhost:8800/136-ajax/1.txt")
//3、send
xhr.send()
//4、接收数据,注册一个事件,表示和后端接上头了
xhr.onreadystatechange=function(){
if(xhr.readyState===4 && xhr.status===200){
console.log("数据解析完成",xhr.responseText)
}else if(xhr.readyState===4 && xhr.static===400){
console.log("没有找到这个页面")
location.href="404.html"
}
}
</script>
3、ajax 状态码
。ajax 状态码-xhr.readystate
。是用来表示一个 ajax 请求的全部过程中的某一个状态
- readystate === 0: 表示未初始化完成,也就是 open 方法还没有执行
- readystate === 1:表示配置信息已经完成,也就是执行完 open 之后
- readystate === 2 : 表示send 方法已经执行完成
- readystate === 3 : 表示正在解析响应内容
- readystate == 4 :表示响应内容已经解析完毕,可以在客户端使用了
。这个时候我们就会发现,当一个ajax 请求的全部过程中,只有当readystate === 4 的时候,我们才可以正常使用服务端给我们的数据
。所以,配合 http 状态码为 200 - 299
- 一个ajax 对象中有一个成员叫做 xhr.status。
- 这个成员就是记录本次请求的 http 状态码的
4、ajax同步异步
配置open(请求方式,请求地址,是否异步)
true 表示异步请求,一个数据没执行完,后面的可以执行(一块吃饭)
false 表示同步请求,必须等一个数据回来后再执行后面的(一个吃完一个再吃)
5、请求方式
1、get 偏向获取数据
2、post 偏向提交数据
3、put 偏向更新(全部更新:全部从新覆盖)
4、delete 偏向删除信息
5、patch 偏向部分修改(只修改要修改的部分)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<button id="myget">get</button>
<button id="mypost">post</button>
<button id="myput">put</button>
<button id="mypatch">patch</button>
<button id="mydelete">delete</button>
<script>
// get post
/*
请求方式:
1、get 偏向获取数据
2、post 偏向提交数据
3、put 偏向更新(全部更新:全部从新覆盖)
4、delete 偏向删除信息
5、patch 偏向部分修改(只修改要修改的部分)
*/
//node.js下载地址:https://nodejs.cn/download/
//验证是否安装完成:cmd 中输入node -v
//npm -v npm是和nodejs绑定好的
// npm insatll json-server -g
//-g表示全局任何地方都可以使用
//json-server 基于一个JSON文件就可以创建很多的后端模拟接口
//json-server .\test.json --watch 表示时时刻刻监听json文件
myget.onclick=function(){
var xhr =new XMLHttpRequest()
xhr.open("GET","请求地址")
xhr.onload=function(){
if(xhr.status===200){
console.log(JSON.parse(xhr.responseText))
}
}
xhr.send()
}
mypost.onclick=function(){
var xhr =new XMLHttpRequest()
xhr.open("POST","请求地址")
xhr.onload=function(){
if(xhr.status===200){
console.log(JSON.parse(xhr.responseText))
}
}
//提交信息
//post 支持 name=111&age=100
//支持json字符串{"name":"1111"}
/* xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
xhr.send('username=gen&password=123')*/
//JSON格式
xhr.setRequestHeader("Content-Type","application/json")
xhr.send(JSON.stringify({
username:"xiaomin",
password:"147"
}))
}
myput.onclick=function(){
var xhr =new XMLHttpRequest()
xhr.open("PUT","请求地址/要修改的id")
xhr.onload=function(){
if(xhr.status===200){
console.log(JSON.parse(xhr.responseText))
}
}
//提交信息
//post 支持 name=111&age=100
//支持json字符串{"name":"1111"}
/* xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
xhr.send('username=gen&password=123')*/
//JSON格式
xhr.setRequestHeader("Content-Type","application/json")
xhr.send(JSON.stringify({
username:"xiaomin111",
password:"147"
}))
}
mypatch.onclick=function(){
var xhr =new XMLHttpRequest()
xhr.open("PATCH","请求地址/要修改的id")
xhr.onload=function(){
if(xhr.status===200){
console.log(JSON.parse(xhr.responseText))
}
}
//提交信息
//post 支持 name=111&age=100
//支持json字符串{"name":"1111"}
/* xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
xhr.send('username=gen&password=123')*/
//JSON格式
xhr.setRequestHeader("Content-Type","application/json")
xhr.send(JSON.stringify({
username:"xiaomin5555"
}))
}
mydelete.onclick=function(){
var xhr =new XMLHttpRequest()
xhr.open("DELETE","请求地址/要删除的id")
xhr.onload=function(){
if(xhr.status===200){
console.log(JSON.parse(xhr.responseText))
}
}
xhr.send()
}
</script>
</body>
</html>
6、node.js的下载
node.js下载地址: https://nodejs.cn/download/
验证是否安装完成: cmd 中输入node -v
npm -v npm是和nodejs绑定好的
npm insatll json-server -g
-g表示全局任何地方都可以使用
json-server 基于一个JSON文件就可以创建很多的后端模拟接口
json-server .\test.json --watch 表示时时刻刻监听json文件
7、AJAX的封装
function querystringify(obj) {
let str = ""
for (let k in obj) str += '${k}=${obj[k]}$'
return str.slice(0,-1)
}
// 封装 ajax
function ajax(options) {
let defaultoptions = {
url:...
method:"GET",
async: true,
data:{},
headers:{},
success: function(){},
error:function(){}
}
let { ur1, method, async, data, headers , success, error} = {
...defaultoptions ,
...options
}
if (typeof data === 'object' && headers["content-type"]?.indexof("json") > -1) {
data = JsON.stringify(data)
}else{
data = querystringify(data)
}
// 如果是 get 请求,并且有参数,那么直接组装一下 ur1 信息
if (/^get$/i.test(method) && data) ur1 += '?'+ data
// 4. 发送请求
const xhr = new XMLHttpRequest()
xhr.open(method, ur1. async)
xhr.onload = function(){
if (!/^2\d{2}s/.test(xhr.status)){
error(错误状态码:s{xhr.status})
return
}
// 执行解析
try {
let result = JSON.parse(xhr.responseText)
success(result)
}catch (err) {
error("解析失败 ! 因为后端返回的结果不是 json 格式字符串 )
}
// 设置请求头内的信息
for (let k in headers) xhr.setRequestHeader(k,headers[k])
if (/^get$/i.test(method)) {
xhr. send()
} else {
xhr.send(data)
}
}
8、回调地狱(嵌套金字塔)
1、概念
。一个回调函数嵌套一个回调函数的时候
。就会出现一个嵌套结构
。当嵌套的多了就会出现回调地狱的情况
。比如我们发送三个 ajax 请求
- 第一个正常发送
- 第二个请求需要第一个请求的结果中的某一个值作为参数。
- 第三个请求需要第二个请求的结果中的某一个值作为参数
2、回调地狱,其实就是回调函数嵌套过多导致的
。当代码成为这个结构以后,已经没有维护的可能了
。所以我们要把代码写的更加的艺术一些
promise 语法
。为了解决回调地狱
。我们就要使用 promise 语法
9、promise 语法(解决回调地狱(嵌套金字塔)问题)
1、Promise概念
promise 是一个ES6 的语法;承诺的意思,是一个专门用来解决异步 回调地狱 的问题
2、语法
//Promise 构造函数 返回值q是promise对象
//resove 表示成功的回调
// reject 表示失败的回调
var q=new Promise(function(resolve,regjct){
})
q.then(function(){
//兑现承诺(满足条件),这个函数被执行
}).catch(function(){
//拒绝承诺(不满足条件),这个函数就会被执行
})
。promise 就是一个语法
- 我们的每一个异步事件,在执行的时候,都会有三个状态,执行中/成功/失败
。因为它包含了成功的回调函数
。所以我们就可以使用 promise 来解决多个 ajax发送的问题
3、promise 封装AJAX
function pajax(option){
return new Promise((resolve,rejext)=>{
ajax({
...option,
success(res){
resolve(res)
},
error(err){
reject(err)
}
})
})
}
4、async/await
。async/await 是一个es7的语法
。这个语法是 回调地狱的终极解决方案
。语法:
async function fn({
const res = await promise对象
}
。这个是一个特殊的函数方式
。可以await一个promise 对象
。可以把异步代码写的看起来像同步代码
。只要是一个promiser 对象,那么我们就可以使用 async/await 来书写
//方法一:
// async 让函数里面的内容异步执行
async function test(){
var res = await pajax({
url:"",
data:{}
})
//等待res执行完后再执行res1
var res1 = await pajax({
url:"",
data:{
newsId:res[0].id
}
})
return res1
}
//调用方法并在函数外面处理结果
test().then(res=>{
console.log("返回结果",res)
}).catch(err=>{
console.log(err)
})
//方法二:内部错误信息
async function test(){
try{
var res = await pajax({
url:"",
data:{}
})
//等待pajax执行完后再执行打印
var res1 = await pajax({
url:"",
data:{
newsId:res[0].id
}
})
}catch(err){
console.log("err",err)
}
}
//调用方法
test()
5、fetch
XMLHttpRequest 是一个设计粗糙的API,配置和调用方式非常混乱,而且基于事件的异步模型写起来不友好,所以出现了fetch,fetch取代了XMLHttpRequest
如:
function test(){
fetch("接口链接",{
method:"请求方式",headers:{},
body:JSON.stringfy({
"name":"xxxxx",
"age":18
})
})
//获取对象
.then((res)=>{
if(res.ok){
return res.json())//res.json() res.text()
}else{
return Promise.reject({
status:res.status,
statusText:res.statusText
})
}
})
//获取值
.then(res=>{
console.log(res)
}).catch(err=>{
console.log(err)
})
}
十、cookie
1、cookie的特点
1.只能存储文本
2单条存储有大小限制4KB左右;数量限制 (一般浏览器,限制大概在50条左右)
3.速取有域名限制:不可跨域读取,只能由来自 写入cokie的 同一域名 的网页可进行读取。简单的进就是,哪个服务器发给你的cookie,只有哪个服务器有权利读取
4.时效限制: 每个cookie都有时效,默认的有效期是,会话级别: 就是当浏览器关闭,那么cookie立即销毁,但是我们也可以在存储的时候手动设置cookie的过期时间
5.路径限制: 存cookie时候可以指定路径,只允许子路径读取外层cookie,外层不能读取内层
2、cookie的操作
<script>
function(){
//值和路径设置
document.cookie="username=xiaoming;path=/155-cookie/aaa"
document.cookie=:"age=18"
//过期时间设置
var date =new Date()
date.setMinutes(date.getMinutes()+1)
document.cookie=`username=xiaoming;expires=${date.toUTCString()}`
//获取cookie的值
console.log(document.cookie)
}
</script>
十一、jsonp
sonp(SON with Padding)是json 的一种“使用模式”,可以让网页从别的域名(网站)那获取资料,即跨域读取数据。为什么我们从不同的域 (网站)访问数据需要一个特殊的技术(JSONP 呢?这是因为同源策略
const script = document.createElement('script')
script.src = './kerwin.txt!
document.body.appendchi1d(script)
十二、闭包
函数内部返回一个函数,被外界所引用.
这个内部函数就不会被销毁回收。
内部函数所用到的外部函数的变量也不会被销毁。