JavaScript 学习笔记
ECMAScript语法
javascript的书写位置
1. 共三种,外部内部行内。
2. 注意:外部js标签的里面不要写代码,因为会被忽略
3. 行内一般用在vue里面会比较多
正则表达式
使用场景
- 验证表单:匹配字符串等
- 敏感词替换
- 关键字提取
语法
/ /是正则表达式字面量
const reg=/表达式/
reg.test(匹配的字符串)//匹配返回true,否则返回false
reg.exec(匹配字符串)//匹配返回数组,否则null
对应字符
- 普通字符:/字符/ 只能匹配字符相同的字符
- 元字符:[a-z]可以匹配字符a~z [0-9]匹配字符0~9
- 边界符:^后跟以什么开头 $后跟以什么结束
/^ $/代表精确匹配
const reg=/吴/ //只要字符串里面有吴这个就可以匹配,'吴吴吴'是匹配成功的
const reg=/^吴$/ //字符串里面只能由吴这个字符才可以匹配,'吴吴吴'是匹配失败的
- 量词(表示重复次数)
ps:量词只服务于它前一个匹配的模式 如
/[a-z][0-9]{1,2}/
这里的{1,2}只服务于{0-9}
量词 | 说明 |
---|---|
* | 重复零次或多次 |
+ | 重复一次或多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或多次 |
{n,m} | 重复n到m次 |
- 字符类
/d代表[0-9]
匹配字符串集合:[abc]表示:只要匹配 a或b或c 就可以,即:只选一个
允许连写:[a-zA-Z0-9]表示:字母和数字只要匹配一个就行
复杂:/ [a-zA-Z0-9_-] /表示:字母数字和 '_ ‘与’ -'字符匹配一个就行
/ ^1[0-8]{3}[a-z]$ / 表示:第一个字符必须是1且后三个字符要在0-8里选最后一个字符在a-z里选,共5个字符匹配
[ ]里面的^表示取反,一定要写在中括号内
. 表示除了换行都可以
-
预定义类
| 预定义类 | 说明 |
|:–: |:---- |
| \d | 匹配0-9之间的任一数字,相当于[0-9] |
| \D | 匹配所有0-9以外的字符 |
| \w | 匹配任意的字母、数字和下划线 |
| \W | 除所有字母、数字和下划线以外的字符 |
| \s | 匹配空格 (包括换行符、制表符、空格符等) |
| \S | 匹配非空格的字符,相当于[ltlrlnlvf] | -
修饰符
规定某些细节,如是否区分大小写,是否支持多行匹配,一般用于非精确匹配
语法:
/表达式/修饰符
是写在表达式外的
i:是ignore缩写,表示匹配是不区分大小写
g:是global缩写,表示匹配时匹配所有满足表达式的结果(因为一般正则表达式只要匹配到了就返回),用在替换敏感词的应用上
字符串.replace(/正则表达式/,'替换的文本')
const str='你真是个混蛋啊,大混蛋'
str.replace(/混蛋/g,'**')//不修改源字符串,而是返回字符串,'你真是个**啊,大**'
三个定义变量的关键字
var
**1.**函数在内部时用var定义一个变量,它是局部变量。但如果直接对一个变量赋值,则变量视为全局变量(此做法不推荐,严格模式下会抛出错误)
2. var声明提升
function foo(){
//var age;
console.log(age);
var age=26;
}
foo();//undefined
此操作不会报错,var声明变量会自动提升到函数作用域最顶部进行隐式声明。
**3. **利用同一个变量名字重复定义赋值是允许的,值为最后一次赋值。
var age=12;
var age=36;
let
1. let同var类似,但是let声明范围是块作用域 ‘’{}‘’,而var的作用域是函数作用域。块作用域是函数作用于的子集,固可以用var的地方可以用let。
if (true) {
var name='matt';
console.log(name);
}
console.log(name);//可以运行
if(true) {
let age=16;
console.log(age);
}
console.log(age);//错误,age在if{}块内结束后销毁
**2.**块作用域不允许重复定义
3. var与let的不同作用域
var name='html';
console.log(name);//html
//这里是块,var只会重复覆盖掉先前定义的值
if(true) {
var name='css';
console.log(name);//css
}
console.log(name);//css
//改成函数后,里面定义的函数结束时便消失,不会影响先前的定义
// var name='html';
// console.log(name);html
// function foo(){
// var name='css';
// console.log(name); css
// }
// foo();//html
// console.log(name); html
let age=0;
console.log(age);//0
if(true) {
let age=1;
console.log(age);//1
}
//if块内的age与先前定义的age不同,块结束,该块作用域的age销毁
console.log(age);//0
总结来说:var函数内与函数外同名的变量相互不影响,let块外与块内的同名变量相互不影响。
**4. **let声明的变量不会在作用域中被提升,let在全局作用域声明的变量不会成为windows对象的属性。
5. for循环要用let初始化循环变量,var会导致泄漏到循环体外。
for(var i=0;i<5;i++){
}
console.log(i);//i=5;
const
1. 与let类似,但是声明时必须初始化,且无法修改const声明的变量。如果const变量引用的时对象,修改对象里面的属性是允许的。
2. 一般不用const定义循环,但可以在for-in,与for-of中起到好的效果,在其中起到重复定义一个新变量的作用。
for(const key in {a:1,b:2}){
console.log(key);//a,b
}
for(const value of[1,2,3,4,5]){
console.log(value);
}
3 在声明变量的时候先用const
const arr=[1,2,3]
arr.push(1)//允许,因为arr本身的地址并未变所以可以操作
const obj={
uname:'123',
age:21
}
obj.sex='man'//直接添加对象的属性也可以,因为对象本事是引用,它的地址并没有变
如图所示
数据类型
Undefined
**1.**未声明和声明的变量用typeof的值都是undefined,声明了未初始化的undefined是一个假值(FALSE),未声明的变量会报错
NULL
1. NULL与Undefined在"="操作符下相等,Undefined本身是由NULL派生而来的,但两者关系不大
2. NULL是用来初始化对象的,typeof(NULL)的结果是object,在对象未被赋值的情况下要赋值NULL
3. NULL是一个假值
Boolean
1. true≠1,false≠0,且区分大小写,其他形式的都是标识符。
2. Boolean()函数:Boolean当普通函数调用时,如果参数是空、“”、+0、-0、NaN、null、undefined和false则返回基本类型false,其他值的参数返回true。
Number
1. 可以表示浮点数和整数,正零和负零视为同等的。
2. 八进制的开头必须是0,若超过范围就视为十进制,严格模式下要用0o前缀。十六进制前缀0x,区分大小写
let Num1=070;//八进制的数,对应十进制56
let Num2=090;//无效的八进制数,当成十进制90
3. 浮点值:由于浮点数的内存是整数的两倍,ES总是趋向于化为整数计算
let floatNum1= 1.1;
let floatNum2= .1 ;//视为0.1,但不推荐这么写
let floatNum3= 1.0;//视为整数1
let floatNum4= 1.25e5//科学计数法,125000
4. 浮点数的精确值:精确度达到17位小数,浮点数计算中不可以出现等于操作,永远不要测定某个特定的浮点值
if( a + b =0.3){
console.log("You get 0.3");
}//不要这么做!!!
//0.1+0.2得出的是3.00000000000000004
//原因是0.1与0.2无法化为整的二进制数,会有无限循环,而小数的精确值有17位会在最后舍入。
5. Number.MIN_VALUE是Number可以表示的最小值,Number.MAX_VALUE是Number可以表示的最大值。超过最大值返回Infinity(无穷大),小于最小值返回-Infinity
6.NaN
- 分子分母同时除0的情况下返回NaN
- 若分子非0,根据分母的有符号无符号0返回Infinity/-Infinity
- isNaN()函数
console.log(isNaN(NaN))//true
console.log(isNaN(10))//false,为数值10
console.log(isNaN("10"))//false,可以转换为数值10
console.log(isNaN("blue"))//true,非数值
console.log(isNaN(true))//false,可以转换为数值1
6.数值转换
- Number()函数:主要提供字符串数值转数值操作,一旦遇到非数值则返回NaN
console.log("hhh")//NaN
console.log(true)//1
console.log("123blue")//NaN
console.log("000011")//11,自动忽略前0
console.log(null)//0
- parseInt()函数:主要获取字符串里的数值,只要开头不是"+/-/数值"则返回NaN,可以获取字符串前的数值,但没法获取字符串后的数值,进制都转为十进制输出。可以传第二个参数,决定字符串里的数字按x进制解析,以十进制输出,不传参视为十进制。
console.log("123blue456")//123
console.log("abc")//NaN
console.log("0xF")//15
console.log("11",16)//17,按16进制解析,十进制输出
- parseFloat()函数:同parseInt相似,但是只能解析十进制,也有取整倾向
String
1字符字面量.
- 字符串有length方法可以知道字符数*( ps:若包含双字字符,length可能不准确 )*
- 转义字符算一个字符
console.log("123\n".length)//4
- 字符串是不可变的,重新赋值会将原来的字符串销毁,再申请新的空间放入新赋值的值。
- toString()方法:变量的方法,将数值转换为字符串形式,可以传入参数,参数代表x进制输出
let num=1
console.log(num.toString(2))//"0010"二进制输出
- String()方法:库的方法,可以直接调用,先调用值的toString方法(若存在),否则null返回null,undefined返回undefined
2.模板字面量
- 由一对反引号(
let str1=`abcdef
gh`
console.log(str1)
//abcdef
//gh
//包含了换行字符
- 字符插值:
通过${}实现,直接插入即可,无需逗号分隔
插值表达式中也可以调用函数、方法和自己的值
typeof 得到的也是string类型
let a="World"
console.log(`Hello,${'World'}!`)//Hello,World!
console.log(`Hello,${a}!`)//Hello,World!
a=`${a}123`//a="World123"
- String.raw
console.log(String.raw`abc
123`)
//abc
//123
console.log(String.raw`abc\n123`)
//"abc\n123"
3.标签函数
- 定义:是唯一的,不可以变的,是对象属性的唯一标识符
Object类型
- 存在属性与对象
操作符
一元操作符
1.递增递减操作符
- 前缀表达式在(++i)发生前进行变量加减,后缀表达式在(i++)发生后进行变量加减
- 可以作用在字符串 布尔值 浮点值等等上
let i=1;
console.log(i++ + ++i + i)//7
//i++值是1,但是进行下一步加的时候i变成了2
对于字符串,先转换为数值在操作
对于布尔值,ture->1,false->0
2.位操作符
- 默认以十进制输出
- 底层逻辑内存,我们只需要将整数视为32位即可
本身所有数值是64位,位操作会先转为32位,结束后将结果再转为64位
- 特殊值NaN Undefined在位操作中会被当成0处理
- 其他会隐式的进行Number()再操作
- 按位非
0变1,1变0 十进制的视觉效果便是,原数被取反-1
let num1=25
console.log(~num1)//-26
- 位操作会将值转为2进制,输出时会省略32位中多余的0
- 左移(<<)会保留符号位
-2左移5位,-2*25,结果是-64
- 有符号右移(>>)保留符号
- 无符号右移(>>>),会给空位补0,对于负数来说会造成比较大的影响
let Value=-1//二进制11111111111111...1111
let newValue=value>>>1//二进制011111111111111...1111是个很大的正数
3.布尔操作符
- 逻辑非 :可以将任何值转为布尔值
!!可以返回值的真正布尔值
0 “” NaN 对应的布尔值都是false
- 逻辑与&&
可以操作任何类型的数,不限于布尔值,返回值也可以不是布尔值
只要有一个操作数不是布尔值,结果也不一定是布尔值第一个操作数是对象,返回第二个操作数
两个操作数都是对象,返回第二个操作数
注意短路原则:一错全错
- 逻辑或||
类似于逻辑与
多用于两个值进行选择,第一个操作数是首选,第二个操作数为次选,只有在第一个操作不正常的条件下,会选择第二个操作数
let myObject= preferredObject || backupObject
4.指数操作符
- Math.pow() = **
console.log(Math.pow(3,2));//9
console.log(3**2)//9
5.加法操作符
- 出现字符串,之后的当成字符串拼接、
console.log(3+2+"hello"+5+7)//5hello57
需要进行算术运算加上括号即可
加减法运算中 ""与null 当成0计算
6.关系操作符
- 操作数都是数值当成大小比较
- 操作数都是字符串比较字母序(从第一个字符开始比,相同就比下一个,同字符串长度无关)
- 一个操作数是数值,将另一个转化为数值比较
- 若数值与非数值字符比较,结果总为flase
console.log("a">4);//flase
console.log("a"<=4);//flase
- 数值字符串比较容易出错 如:“23”>“3” 结果是flase,因为3比的是第一个字符的acsill码
- 大小写字符串比较容易出错,因为小写字母的acsill码大于大写字母
console.log(“a”<“B”)//flase
7.运算符优先级

数组
- 声明
let arr=[]
可以不给初值 - 元素:可以是各种字面量的杂合,允许同时存在各种类型的字面量
- 打印arr
let arr=[1,2,3]
alert(arr)//1,2,3 逗号也会跟着显示
console.log(arr)//[1,2,3] 方框也会跟着显示
doument.write(arr)//同alert
- 增:
末尾增:数组.push(元素1,元素2....)
可以将一个或者多个元素添加到数组末尾,并且返回新数组长度
开头增:数组.unshift(元素1,元素2....)
,效果同push() - 删:
末尾删:数组.pop()
,只能删除一个并且返回该值
开头删:数组.shift()
,同pop()
指定删:数组.splice(start,deletCount)
两个参数分别为删除的起始下标和删除个数,可以删除从start开始的deletCount个元素,如果不指定具体个数就后面全删完 - 排序:
arr.sort()//默认数组排列为升序
arr.sort(function(a,b){
return b-a//结果为降序
})
- map与join方法
map():可进行元素拼接,返回一个新的数组(类似于for…each)
const newArr=array.map(function(操作元素ele,索引index){
return ele+'颜色'//注意return要在同一行
})
join():将所有的元素拼接为字符串
const array=['1','q','+']
array.join('')//拼接为'1q+'
array.join()//拼接为'1,q,+'
函数
- 函数声明
function 函数名(){//函数名前缀应为动词
}
- 函数参数
function getSum(strat,end){//这两参数叫形参
}//传参无需let定义
function test(a=0,b=0){//默认类型时undefined
console.log(a+b)//a,b可以给默认初值,有参数传入时不会执行赋初值操作
}
test(1,2)
test()//可以执行不会报错
- 返回值:return可以有也可以没有,没有的时候默认值为undefined
funtion getArr(x,y){
return [x,y]//可以返回数组
}
- 函数体调试:F10->单步执行跳过函数 F11->单步执行进入函数
- 重名情况:
两个相同函数名后面覆盖前面的函数
- 参数不匹配
实参多于形参,前面的正常赋值,多余的实参忽略
实参小于形参,NAN
- arguments:?
- 匿名函数
fn1()//错误,使用的是let
let fn1 = function () {
console.log('我是真帅')
}//匿名函数遵循let的死区,只能先声明再用
fn1()//正确
fn2()//正确
function fn2() {
}//具名函数会提升声明
- 立即执行函数
写法1:
(function( ){ }) ( );
可加名字亦可不加,先写两个括号,在第一个括号里写入funtion(){}
写法2:`(function(){}())·
后面一个括号相当于对函数的调用,且里面的参数为实参
一定要再结束后加分号
对象
对象里的键值对是无序的
对象的查(两种方法)
let obj={
name:'ffff',//最好不要个对象的属性命名为name
age:12,
'student-name':'wyf' //属性名可以用''也可以省略,但是有横线或者空格就要用
}
console.log(obj.name)//直接点加属性名
console.log(obj['student-name'])//中括号+引号+属性名,引号是必须的不论命名时是否有
console.log(obj['age'])
对象中的方法
let obj={
song: funtion(){
console.log('我在唱歌')
}
}
obj.song()//调用对象方法
对象遍历
- for in 遍历方法
let arr[]={'123','qqqq'}
for(let k in arr){
console.log(k)//这个k是个字符串型,一般不用于遍历数组
}
let fff={
uname:'qwe',
age:12
}
for (let k in fff) {
console.log(k)//得到的是属性,也是字符串'uname'、'age'
console.log(fff.k)//错误相当于fff.'uname',肯定有语法错误
console.log(fff[k])//正确
}
遍历数组对象
数组最好还是用传统的for方法遍历
let student =
[
{ name: '小er', age: 13, phoneNum: 110 },
{ name: '小皮', age: 12, phoneNum: 114514 },
{ name: '小的', age: 15, phoneNum: 119 },
{ name: '小分', age: 16, phoneNum: 120 }
]
for (let i = 0; i < student.length; i++) {
console.log(student[i].name)
}
内置对象
- Math.random()
可以取到**[0,1)**之间的数,左闭右开
Math.random()*(10+1)//想要[0,10]就再里面加1, ->[0,11)
Math.random()*(10)+1//外面加1,给区间两头都加1, ->[1,11)
Math.floor(Math.random(M-N+1))+N//返回区间[N.M]的数字
Math.floor(Math.random()*arr.length)//可以获取任意一个数组索引
如果想要闭区间就取原本区间上+1就可以了
- Math.floor()
返回一个小于等于数的最大整数
类似于ParseInt()函数
DOM
监听器
addEventListener(‘事件类型’,function(){ })
鼠标事件
mouseleave 鼠标离开
mouseenter 鼠标进入
一般不适用mouseover与mouseout 因为这两个自带冒泡阶段,容易出错
键盘事件
keyup 键盘按下
keydown 键盘抬起
表单光标事件
focus 获得焦点
blur 失去焦点
change
失去焦点且value内容改变
主要用在表单验证上,比blur友好,因为只有当失去焦点且内容与上一次失去焦点不同时才会触发
用户输入事件
input 输入
事件
对象事件e
可以获取事件的属性
addEventListener('click',function(e){
console.log(e)//可以获取事件属性
})
addEventListener('keyup/keydown',function(e){
console.log(e.key)//获取键入的值
})
环境变量this与回调函数
环境变量:函数内部的特殊变量this,代表函数的运行环境,一般泛指调用者
box.addEventListener('click',function(){
this.style.width='300px'//这里就是调用者box
})
回调函数:函数a的参数是函数b的返回值,此时称函数b为回调函数
事件流
事件执行中的流动顺序:
- 捕获阶段:从父到子
DOM.addEventListener(事件类型,事件处理函数[,是否使用捕获机制])//中括号代表可选,默认为冒泡机制只有为true时为捕获机制
- 冒泡阶段:从子到父(常用且默认存在)
当一个元素触发事件后(即使没有建立对应监听器)会依次向上调用所有的父级元素同名事件
<ul>
<li></li>
<li></li>
<li></li>
</ul>
//对父ul绑定点击事件,li被点击时(没有绑定具体点击事件)会冒泡调用ul的点击事件
- 阻止冒泡
要获取function里面的e事件对象
e.stopPropagation
- 事件解绑
匿名函数无法解绑
function fn(){
}
btn.addEventListener('click',fn)
btn.removeEventListener('click',fn)
- 事件委托
利用冒泡机制,减少注册次数
<ul>
<li></li>
<li></li>
<li></li>
</ul>
e.target//获取点击的具体对象,可以获取到子元素li
e.target.tagName//可以获取具体的对象的类型
//如p->'P',li->'LI'就此判断哪些子元素要执行事件
- 阻止默认事件
可以阻止表单域提交或者a链接的跳转
const form=document.querySeletor('form')
form.addEventListener('click',function(e){
e.preventDefault()
})
- 页面加载事件
以下两个都是写在body标签前的script标签内
ps:由于代码是从上往下执行,一般js要写在body后才能获取到dom元素标签
load: window添加,等所有资源加载完才执行里面的操作
DOMContentLoaded: document添加,无需等待样式表或者图片完全加载
 <html>
<script>
window.addEventListener('load',function(){
//执行操作
})
document.addEventListener('DOMContentLoaded',function(){
//执行操作
})
</script>
<body>
</body>
</html>
- 页面滚动事件
事件名:scroll
获取html这个标签:document.documentElement
滚动的属性:scrollTop
,scrollLeft
分别因为滚动上或者左边表示被卷去了多少,且可读可写
补充:window.scrollTo(x,y)滚动到x,y的坐标
滚动事件不只html可以添加,其他盒子由滚动条也可以添加
获取的属性是像素(数字型),不含单位
介绍这两个属性:
零散知识点
获取选择器(常用以下的,其他已经逐渐淘汰)
document.querySelecter('div')//标签选择器
document.querySelecter('.box')//class类选择器
document.querySelecter('#id')//ID选择器
选择器的属性修改
<div></div>
<script>
const box=document.querySelecter('div')//此时的box是一个对象即div
box.innerText='123'//给div里面填充文字'123'
</script>
属性改值基本要用字符串
通过style操作样式
注意!类似于background-color有短横线连起来的英文采取小驼峰命名方法拼写,不然会出错
补充小驼峰命名法:
除第一个单词之外,其他单词首字母大写。方法名、参数名、成员变量、局部变量需要使用小驼峰命名法(lowerCamelCase)。
const box=document.querySelecter('div')
box.style.color='red'
box.style.backgroundColor='#ffffff'
box.style.width='300px'//单位一定要有,相当于这个字符串将样式中冒号后的值覆盖了
box.style.borderTop='10px'//原border-top
通过类名修改样式
步骤:1、先提前写好一个类 2、通过 对象.className='类名’将类的样式添加进去
缺点:容易覆盖原来的类
.width_100 {
width:100px;
}
const box=document.querySelecter('div')
box.className='width_100'//要留意原本的对象有没有类名,有的话需要加上
box.className='width_100 origin_className'//加上原来类名
通过classList修改样式
类名不加点,并且是字符串
box.classList.add('active')//追加类
box.classList.remove('active')//删除类
box.classList.toggle('active')//切换类,有就删除,没有就追加
innerText与innerHTML区别:
前者只是将文字输入盒子内,标签不会生效,会被识别成文字。后者可以识别文字中的标签
自定义属性data
- 标准属性:标签自带的属性,如class id title disabled
- 自定义属性:
html5中新定义的 data-自定义属性
标签一律以data-开头(可以说是编码风格硬性要求)
DOM对象以dataset方法获取
注意该属性是string类型的
<body>
<div class="box" data-id="10"></div>
</body>
<script>
const box=document.querySelector('.box')
console.log(box.dataset)//相当于box类所在标签的所有自定义属性都在dataset这个对象里,是对象的属性
</script>
计时器
- setInterval
setInterval(函数,循环时间(ms))
计时器返回的是计时器的id,关闭时需要用到此id
如果是匿名函数可以直接写,有名函数注意只用写函数名不用括号解决页面初始化时空白,可以先制行一次计时器里的函数
let n = setInterval(function(){
clearInterval(n)//关闭id为n的计时器
},1000)
let m = setInterval(fn,1000)
let k = setInterval(function(){
next.click()//可以直接执行某个对象的点击事件
},1000)
延时器
- setTimeout(function( ) { },延迟运行时间(ms) )
- clearTimeout( id )清除延迟器(递归会用到)
元素宽高与元素于页面的位置
- 元素宽高1:clientWidth&clientHeight-----都是元素的属性(不包含border,margin,滚动条)
可以通过js动态获取元素的宽高
-
元素宽高2:offsetWidth&offsetHeight:(包含padding,border)
-
元素在页面的位置:offsetLeft&offsetTop
获取元素距自己有定位的父级的距离 (只读不可写)
- 总结:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X3Hdg3xX-1685947115731)(…/typora_img/元素尺寸总结.png)]
Date()对象
时间戳:从1970年1月1日 00:00:00 到指定时间的毫秒数
const date=Date()
//获取当前时间,重要!
new Date().toLocaleString()//'2021-5-24 08:12:13'
date.getFullYear()//四位年份
date.Month//取值0~11的月份
date.getDate()//日
date.getDay()//星期,取值0~6
date.getHours//时
date.getMinutes//分
date.getSeconds//秒
/*三种获取当前时间的时间戳方法*/
//1.
const date=Date()
date.getTime()//不可获取指定时间戳
//2.
const date=+new Date()//给参数可以获取指定时间的时间戳 ('2023-5-24 08:00:00')
//3.
Date.now()//不可获取指定时间戳
查找DOM元素
主要目的:获取元素(对象),不需要具体的文本内容
都是属性,固通过 ’ . ’ 获取
- 父节点:子元素.parentNode
返回的是dom对象 - 子节点:1.childNodes
获取元素加文本内容不常用-
2.children(重点)
-
仅获得所有(亲儿子)元素节点,且返回一个伪数组
- 获取节点的前后兄弟节点
node.previousElementSibling
&node.nextElementSibling
创建节点与追加节点
// // 1. 创建节点
const div = document.createElement('div')//直接写节点类型
// 2. 追加节点 作为最后一个子元素
document.body.appendChild(div)
const ul = document.querySelector('ul')
const li = document.createElement('li')
li.innerHTML = '我是li'
ul.appendChild(li)
ul.children
// 3. 追加节点
// insertBefore(插入的元素, 放到哪个元素的前面)
ul.insertBefore(li, ul.children[0])
克隆节点
不同于直接赋值,赋值只是获取到该dom元素的控制权
cloneNode(true)参数为true表示为深克隆(即整个标签与内容一起),参数为空为浅克隆只获取标签(少用)
const ul = document.querySelector('ul')
// 1 克隆节点 元素.cloneNode(true)
const li1 = ul.children[0].cloneNode(true)
// 2. 追加
ul.appendChild(ul.children[0].cloneNode(true))
return注意
当要返回时,return 当前行必须要有内容,不然会返回空(多发生错误于模板字符串)
//错误示范!
function fn(){
return
`
<div>
</div>
`
}
//正确示范!
function fn(){
return `
<div>
</div>
`
}
form表单清空
form.addEventListener('submit',function(){
this.reset()//清空表单,可能没有代码提示
})
BOM
eventloop事件循环
- 同步任务: 指的是在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务。
- 异步任务: 指的是不进入主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
如计时器,上下文执行到该处会将其交给异步处理机制(即使时间间隔是0ms),然后主线程继续执行,计时器在异步机制处理处达到该执行的时候,会将其交给异步队列,等待主线程空闲,主线程会查看异步队列是否有任务,有则调入主线程并执行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZCI9Hh2Q-1685947115732)(…/typora_img/JS执行机制.png)]
location对象
- location.href:可以改变当前页面的地址
- location.search:可以获取url 中’ ? '后的字符串
如:
https://www.bilibili.com/video/BV1YL7N?np=128&vd_source=f453b8f65d2e4786f8d66fbcc5b1
- location.hash:获取url ’ # '后面的字符串
navigator对象
浏览器的信息
history
历史记录前后跳转
- back()后退
- forward()前进
- go(n) 前进或后退n个页面
localStorage本地存储
- 数据存储在浏览器
- 设置读取方便,页面刷新关闭数据不会消失
- 约为5M的容量
- 同一浏览器多窗口共享数据
- 以键值对形式存在,
数据皆为字符串形式
- sessionStorage 存储与localStorage类似 ,但其生命周期为关闭浏览器窗口
- 具体操作实现:
localStorage.setItem('key',value)
//key:在存储的变量名,需要为字符串形式,value:存入的数据
localStorage.getItem('key')
//返回的是字符串
//JSON操作
JSON.parse()//字符串翻译为复杂数据类型
JSON.stringify()//复杂数据类型翻译为字符串
//搭配使用
const arr=[]
localStorage.setItem('key', JSON.stringify(arr))
const arr = JSON.parse(localStorage.getItem('key')) || []//没有返回空数组
//复杂数据类型包括数组和对象等
localStorage.remove('key')//移除数据
瞬记知识点
prompt:
- 使用方法
let str1=prompt("请输入:");//获取的str1变量是string类型,获取表单时也是如此
let str2=+prompt("请输入:");//加号将str2转换为number型
confirm
确认表单
confirm('确认吗?')
待学知识点
- 正则表达式
- 捕获组
- 伪类选择器
- 子类选择器
- flex弹性布局
- 属性选择器
完成的练习
轮播图终极实现
滚动卡住你
电梯导航
学生信息表录入渲染(没有本地存储版)
学生信息表统计(有本地存储)
注册界面验证
HTML&CSS瞬记
transform
- transformX(10px) :从最初的位置为原点,位移到坐标为10px的地方去
如果变化为transformX(20px):从效果上来说是从10px位置位移到20px位置
- 页面滚动效果
html {
scroll-behavior:smooth;
}
插件使用
swiper 轮播图
解决过的问题
localStorage 丢失
如果用的是Chorme浏览器,页面关闭后会丢失localStorage数据,可能是设置的问题