一、JS基础
1.1 引入JS的方式
- 写在
button按钮的onclick属性里面,点击按钮,执行JS代码
1
| <button onclick="console.log('点击按钮')">点击按钮</button>
|
- 写在超链接的href属性中,点击超链接,执行JS代码(不推荐使用)
1 2 3 4
| <a href="javascript:alert('让你点你就点!');">你也点我一下</a> <!-- 没有javascript限定符,点击超链接会显示一串英文 --> <a href="javascript:;">你也点我一下</a> <!-- 点击没有任何反应,只是用于JS处理一些功能 -->
|
- 写在
script标签里面【内部方式】
1 2 3
| <script> console.log("写在script标签里面的JS代码"); </script>
|
- 写在外部的JS文件中,通过
script标签引入(推荐使用)【外部方式】
此时不能在标签内部写代码,即使编写,浏览器也会忽略
1
| <script src="./js/script.js"></script>
|
1.2 注释
1.2.1 单行注释
1.2.2 多行注释
1.3 结束符
;代表一段代码的结束,可以省略不写,使用回车替代
1.4 输入和输出
1.4.1 输出
1 2
| alert() document.wirte()
|
1.4.2 输入
向 prompt() 输入任意内容会以弹窗形式出现在浏览器中,一般提示用户输入一些内容
1.5 变量
1.5.1 声明
声明(定义)变量有两部分构成:声明关键字、变量名(标识)
关键字是let、var
1.5.2 赋值
声明(定义)变量相当于创造了一个空的“容器”,通过赋值向这个容器中添加数据
1.5.3 关键字
以下是使用 let 时的注意事项:
- 允许声明和赋值同时进行
- 不允许重复声明
- 允许同时声明多个变量并赋值
- JavaScript 中内置的一些关键字不能被当做变量名
以下是使用 var 时的注意事项:
- 允许声明和赋值同时进行
- 允许重复声明
- 允许同时声明多个变量并赋值
1.5.4 变量命名规则
- 只能是字母、数字、下划线、$,且不能以数字开头
- 区分大小写
- JavaScript 内部已占用于单词(关键字或保留字)不允许使用
- 见名知意
1.6 常量
使用 const 声明的变量称为“常量”
使用场景:当某个变量永远不会改变的时候,就可以使用 const 来声明,而不是let
命名规范:和变量一致
注意: 常量不允许重新赋值,声明的时候必须赋值(初始化)
1.7 数据类型
通过typeof关键字检测数据类型
1.7.1 数值类型
JavaScript 中的数值类型与数学中的数字是一样的,分为正数、负数、小数等
1.7.2 字符串类型
通过单引号( '' ) 、双引号("")或反引号(````)包裹的数据都叫字符串
单引号和双引号没有本质上的区别,推荐使用单引号
注意事项:
- 无论单引号或是双引号必须成对使用
- 单引号/双引号可以互相嵌套,但是不以自已嵌套自已
- 必要时可以使用转义符
\,输出单引号或双引号
1.7.3 布尔类型
表示肯定或否定时在计算机中对应的是布尔类型数据,它有两个固定的值 true 和 false , 表示肯定的数据用
true ,表示否定的数据用 false
1.7.4 undefined
未定义是比较特殊的类型,只有一个值undefined,只声明变量,不赋值的情况下,变量的默认值为undefined,
一般很少直接为某个变量赋值undefined
1.8 类型转换
1.8.1 隐式转换
某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换称为隐式转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <script> let num = 13 let num2 = '2' console.log(num + num2) console.log(num - num2) let a = prompt('请输入一个数字') let b = prompt('请再输入一个数字') alert(a + b); </script>
|
1.8.2 显式转换
通过Number()显式转换成数值类型,当转换失败时结果为NaN(Not a Number)
1.9 运算符
1.9.1 算术运算符
计算失败的时候,显示的结果是NaN
1.9.2 赋值运算符
1.9.3 自增/自减运算符
- ++、– 可以在变量前面也可以在变量后面,在单独使用时并没有差别
- ++在后(后缀式)我们会使用更多
- 只有变量能够使用自增和自减运算符
1.9.4 比较运算符
1.9.5 逻辑运算符
1.9.6 运算符优先级
逻辑运算符优先级: !> && > ||
1.10 表达式
1.10.1 表达式和语句
表达式:可以被求值的代码,并将其计算出一个结果
语句:一段可以执行的代码,是一个行为
1.10.2 分支和语句
分支语句可以根据条件判定真假,来选择性的执行想要的代码
if分支语句 - 范围判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| if(条件表达式) { }
if (条件表达式){ } else { }
if (score >= 90) { alert('成绩优秀,宝贝,你是我的骄傲') } else if (score >= 70) { alert('成绩良好,宝贝,你要加油哦~~') } else if (score >= 60) { alert('成绩及格,宝贝,你很危险~') } else { alert('成绩不及格,宝贝,我不想和你说话,我只想用鞭子和你说话~') }
|
三元运算符
switch语句 - 确定值、必须是全等(数据类型一致)、注意break
1 2 3 4 5 6 7 8 9 10 11
| switch (表达式) { case 值1: 代码1 break case 值2: 代码2 break ... default: 代码n }
|
当分支比较少时,if…else语句执行效率高
当分支比较多时,switch语句执行效率高,而且结构更清晰
内部生成一个跳表,每个常量对应一个内存地址,通过二分查找,锁定常量,跳转至指定位置
1.10.3 循环语句
while循环 - 不确定循环次数
- break 中止整个循环
- continue 中止本次循环
无限循环
1 2 3 4 5 6 7
| while(true) { }
for(;;) { }
|
for循环 - 确定循环次数
1 2 3
| for(起始值; 终止条件; 变化量) { }
|
:::success
注意: for 的语法结构更简洁,故 for 循环的使用频次会更多
:::
循环嵌套
1 2 3 4 5
| for(外部声明记录循环次数的变量; 循环条件; 变化量) { for(内部声明记录循环次数的变量; 循环条件; 变化量) { } }
|
1.11 数组
1.11.1 数组的概念
数组:(Array)是一种可以按顺序保存数据的数据类型(属于对象)
1.11.2 数组的基本使用
定义数组和数组单元
1 2 3 4 5 6 7
| <script> let classes = ['小明', '小刚', '小红', '小丽', '小米'] </script>
|
访问数组和数组索引
1 2
| 1. 访问数组,语法格式为:变量名[索引值] 2. 通过索引值还可以为数组单元重新赋值
|
**数据单元值类型 **
**数组长度属性 **
- 数组对应着一个 length 属性,它的含义是获取数组的长度
数组map方法
1 2 3 4 5 6 7 8 9 10
| <script> const arr = ['red', 'blue', 'pink'] const newArr = arr.map(function (ele, index) { return ele + '颜色' }) console.log(newArr) </script>
|
数组join方法
1 2 3 4 5 6 7 8
| <script> console.log(newArr.join()) console.log(newArr.join('')) console.log(newArr.join('|')) </script>
|
1.11.3 操作数组
push 动态向数组的尾部添加一个单元
unshit 动态向数组头部添加一个单元
pop 删除最后一个单元
shift 删除第一个单元
splice 动态删除任意单元
1 2 3
| let arr = ['red', 'green', 'blue'] arr.splice(1,1) console.log(arr)
|
1 2 3 4 5
| let arr = ['red', 'green', 'blue']
arr.splice(1, 0, 'pink', 'hotpink') console.log(arr)
|
以上方法都是对原数组进行操作
1.12 函数
1.12.1 声明和调用
函数可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行这些被“包裹”的代码逻辑
这么做的优势是有利于精简代码、方便复用
声明(定义)
声明(定义)一个完整函数包括关键字、函数名、形式参数、函数体、返回值5个部分

调用
- 声明(定义)的函数必须调用才会真正被执行,使用
函数名()调用函数
- 函数名的命名规则与变量是一致的,并且尽量保证函数名的语义
参数
- 声明(定义)函数时的形参没有数量限制,当有多个形参时使用 , 分隔
- 调用函数传递的实参要与形参的顺序一致
- 形参和实参
- 形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)
- 实参:调用函数时写在函数名右边小括号里的叫实参(实际上的参数)
返回值
要想获得函数内部逻辑的执行结果,需要通过 return 这个关键字,将内部执行结果传递到函数外部,这个被传递到外部的结果就是返回值
- 在函数体中使用return 关键字能将内部的执行结果交给函数外部使用
- 函数内部只能出现1 次 return,并且 return 下一行代码不会再被执行,所以return 后面的 数据不要换行写
- return会立即结束当前函数
- 函数可以没有return,这种情况默认返回值为 unde
作用域
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域
作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突
- 全局作用域
- 作用于所有代码执行的环境(整个 script 标签内部)或者一个独立的 js 文件
- 处于全局作用域内的变量,称为全局变量
- 局部作用域
- 作用于函数内的代码环境,就是局部作用域。 因为跟函数有关系,所以也称为函数作用域
- 处于局部作用域内的变量称为局部变量
如果函数内部,变量没有声明,直接赋值,也当全局变量看,但是强烈不推荐
但是有一种情况,函数内部的形参可以看做是局部变量
1.12.2 匿名函数
函数可以分为具名函数和匿名函数
匿名函数:没有名字的函数,无法直接使用
函数表达式
1 2 3 4 5 6
| let fn = function() { console.log('函数表达式') }
fn()
|
立即执行函数
1 2
| (function(){ xxx })(); (function(){xxxx}());
|
- 无需调用,立即执行
- 多个立即执行函数之间用分号隔开
1.13 对象
1.13.1 语法
1.13.2 属性和访问
- 属性都是成对出现的,包括属性名和值,它们之间使用英文
:分隔
- 多个属性之间使用英文
,分隔
- 属性就是依附在对象上的变量
- 属性名可以使用
"" 或 '' ,一般情况下省略,除非名称遇到特殊符号如空格、中横线等
可以使用.或[]获得对象中属性对应的值,称之为属性访问
可以动态为对象添加属性,动态添加与直接定义是一样的
1.13.3 方法和调用
数据行为性的信息称为方法,其本质是函数
- 方法是由方法名和函数两部分构成,它们之间使用
:分隔
- 多个方法之间使用英文
,分隔
- 方法是依附在对象中的函数
- 方法名可以使用
""或'',一般情况下省略,除非名称遇到特殊符号如空格、中横线等
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <script> let person = { name: '小红', age: 18, singing: function () { console.log('两只老虎,两只老虎,跑的快,跑的快...') }, run: function () { console.log('我跑的非常快...') } } </script>
|
可以使用.或[]调用对象中的函数,称之为方法调用
可以动态为对象添加方法,动态添加与直接定义是一样的
1 2 3 4 5 6 7 8 9
| <script type="text/javascript"> let student = { run: function() { console.log('跑步中~'); } } student.run() student['run']() </script>
|
无论是属性或是方法,同一个对象中出现名称一样的,后面的会覆盖前面的
1.13.4 null
null 也是 JavaScript 中数据类型的一种,通常只用它来表示不存在的对象
通过typeof检测其数据类型,结果是Object
1.13.5 遍历对象
既遍历对象中的属性,也遍历对象中的方法
1 2 3 4 5 6 7
| let obj = { uname: 'pink' } for(let k in obj) { }
|
1.14 内置对象
1.14.1 Math
属性
Math.PI 获取圆周率
方法
Math.random 生成 0 到 1 间的随机数(包含 0 不包含 1)
Math.ceil 数字向上取整
Math.floor 数字向下取整
Math.round 四舍五入取整
Math.max在一组数中找出最大的
Math.min 在一组数中找出最小的
Math.pow 幂方法
Math.sqrt 平方根
二、Web API
2.1 概念
ES和JS的关系

DOM(Document Object Model)是将整个 HTML 文档的每一个标签元素视为一个对象,这个 对象下包含了
许多的属性和方法,通过操作这些属性或者调用这些方法实现对 HTML 的动态 更新,为实现网页特效以及用户交
互提供技术支撑
2.1.1 DOM树

2.1.2 DOM节点
节点是文档树的组成部分,每一个节点都是一个 DOM 对象,主要分为
元素节点:HTML标签
属性节点:HTML标签中的属性
文本节点:HTML标签中的文本内容
根节点:`标签
2.1.3 Docment
document 是 JavaScript 内置的专门用于 DOM 的对象
1 2 3 4 5 6 7 8 9 10
| <script> console.log(document.documentElement); console.log(document.body); document.write('Hello World!'); </script>
|
2.2 获取DOM对象
querySelector获取满足条件的第一个元素(写选择器)
querySelectorAll获取满足条件的所有元素,返回伪数组(写选择器)
getElementById通过id获取元素节点(直接写ID名称)
getElementByClassName通过class获取元素节点(直接写类名)
任意 DOM 对象都包含 nodeType 属性,用来检检测节点类型
2.3 操作元素内容
修改DOM的文本内容
innerText 将文本内容添加/更新到任意标签位置,文本中包含的标签不会被解析
innerHTML 将文本内容添加/更新到任意标签位置,文本中包含的标签会被解析
2.4 操作元素属性
2.4.1 常用属性修改
1 2 3 4 5 6 7 8
| <script> const pic = document.querySelector('.pic') pic.src = './images/lion.webp' pic.width = 400; pic.alt = '图片不见了...' </script>
|
2.4.2 控制样式属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>练习 - 修改样式</title> </head> <body> <div class="box">随便一些文本内容</div> <script> const box = document.querySelector('.intro') box.style.color = 'red' box.style.width = '300px' box.style.backgroundColor = 'pink' </script> </body> </html>
|
CSS属性若含有 - ,应该用小驼峰命名法
background-color 改为 backgroundColor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>练习 - 修改样式</title> <style> .pink { background: pink; color: hotpink; } </style> </head> <body> <div class="box">随便一些文本内容</div> <script> const box = document.querySelector('.intro') box.className = 'pink' </script> </body> </html>
|
className的方式是新值换旧值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div { width: 200px; height: 200px; background-color: pink; } .active { width: 300px; height: 300px; background-color: hotpink; margin-left: 100px; } </style> </head> <body> <div class="one"></div> <script> let box = document.querySelector('div') box.classList.toggle('one') box.classList.contains('aaa') </script> </body> </html>
|
2.4.3 操作表单元素属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <body> <input type="text" value="请输入"> <button disabled>按钮</button> <input type="checkbox" name="" id="" class="agree"> <script> let input = document.querySelector('input') input.value = '小米手机' input.type = 'password' let btn = document.querySelector('button') btn.disabled = false let checkbox = document.querySelector('.agree') checkbox.checked = false </script> </body>
|
2.4.4 自定义属性
HTML5 专有的 data- 自定义属性
在DOM对象上一律以 dataset 对象方式获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div data-id="1"> 自定义属性 </div> <script> let div = document.querySelector('div') console.log(div.dataset.id) </script> </body> </html>
|
2.5 间歇函数
setInterval 是 JavaScript 中内置的函数,它的作用是间隔固定的时间自动重复执行另一个 函数,也叫定时器函数
1 2 3 4 5 6 7 8 9
| <script> function repeat() { console.log('不知疲倦的执行下去....') } setInterval(repeat, 1000) </script>
|
2.6 事件
事件是用来描述程序的行为或状态的,一旦行为或状态发生改变, 便立即调用一个函数
2.6.1 事件监听
addEventListener 是 DOM 对象专门用来添加事件监听的方法,它的两个参数分别为【事件类型】和【事件回调】
完成事件监听的三个步骤:
- 获取 DOM 元素
- 通过 addEventListener 方法为 DOM 节点添加事件监听
- 等待事件触发,如用户点击了某个按钮时便会触发 click 事件类型
- 事件触发后,相对应的回调函数会被执行
2.6.2 事件类型
click
dblclick
2.6.3 事件处理程序
事件处理程序决定了事件触发后应该执行的逻辑
2.7 事件类型
2.7.1 鼠标事件
鼠标事件是指跟鼠标操作相关的事件,如单击、双击、移动等
mouseenter
mouseleave
2.7.2 键盘事件
keydown
keyup
2.7.3 焦点事件
focus
blur
2.7.4 文本框输入事件
input
2.8 事件对象
任意事件类型被触发时与事件相关的信息会被以对象的形式记录下来,我们称这个对象为事件对象
事件回调函数的【第1个参数】即所谓的事件对象,通常习惯性的将这个对象命名为 event 、 ev 、 e
ev.type 当前事件的类型
ev.clientX/Y 光标相对浏览器窗口的位置
ev.offsetX/Y 光标相于当前 DOM 元素的位置
在事件回调函数内部通过 window.event 同样可以获取事件对象
2.9 环境对象
环境对象指的是函数内部特殊的变量 this ,它代表着当前函数运行时所处的环境
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <script> function sayHi() { console.log(this); } let user = { name: '张三', sayHi: sayHi } let person = { name: '李四', sayHi: sayHi } sayHi() window.sayHi() user.sayHi() person.sayHi() </script>
|
2.10 回调函数
将函数A作为参数传递给函数B,函数A称为回调函数
回调函数本质还是函数,只不过把它当成参数使用
使用匿名函数做为回调函数比较常见
2.11 事件流
事件流是对事件执行过程的描述

任意事件被触发时总会经历两个阶段:【捕获阶段】和【冒泡阶段】
捕获阶段是【从父到子】的传导过程,冒泡阶段是【从子向父】的传导过程
2.11.1 事件和冒泡
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <body> <h3>事件流</h3> <p>事件流是事件在执行时的底层机制,主要体现在父子盒子之间事件的执行上。</p> <div class="outer"> <div class="inner"> <div class="child"></div> </div> </div> <script> const outer = document.querySelector('.outer'); const inner = document.querySelector('.inner'); const child = document.querySelector('.child'); document.documentElement.addEventListener('click', function () { console.log('html...') }) document.body.addEventListener('click', function () { console.log('body...') }) outer.addEventListener('click', function () { console.log('outer...') }) outer.addEventListener('click', function () { console.log('inner...') }) outer.addEventListener('click', function () { console.log('child...') }) </script> </body>
|
当某个元素的事件被触发时,事件总是会先经过其祖先才能到 达当前元素,然后再由当前元素向祖先传递,事件在流动的过程中遇到相
同的事件便会被触发。
事件的执行顺序是可控制的,即可以在捕获阶段被执行,也可以在冒泡阶段被执行
如果事件是在冒泡阶段执行的,我们称为冒泡模式,它会先执行子盒子事件再去执行父盒子 事件,默认是冒泡模式
如果事件是在捕获阶段执行的,我们称为捕获模式,它会先执行父盒子事件再去执行子盒子 事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <body> <h3>事件流</h3> <p>事件流是事件在执行时的底层机制,主要体现在父子盒子之间事件的执行上。</p> <div class="outer"> <div class="inner"></div> </div> <script> const outer = document.querySelector('.outer') const inner = document.querySelector('.inner') outer.addEventListener('click', function () { console.log('outer...') }, true) outer.addEventListener('click', function () { console.log('inner...') }, true) </script> </body>
|
addEventListener 第3个参数决定了事件是在捕获阶段触发还是在冒泡阶段触发
addEventListener 第3个参数为 true 表示捕获阶段触发, false 表示冒泡阶段触发, 默认值为 false
事件流只会在父子元素具有相同事件类型时才会产生影响
绝大部分场景都采用默认的冒泡模式(其中一个原因是早期 IE 不支持捕获)
2.11.2 阻止冒泡
阻止冒泡是指阻断事件的流动,保证事件只在当前元素被执行,而不再去影响到其对应的祖先元素
事件对象中的 ev.stopPropagation 方法,专门用来阻止事件冒泡
鼠标经过事件:
mouseover 和 mouseout 会有冒泡效果
mouseenter 和 mouseleave 没有冒泡效果 (推荐)
2.12 事件委托
1 2 3 4 5 6 7 8 9 10
| <script> const buttons = document.querySelectorAll('table button'); for(let i = 0; i <= buttons.length; i++) { buttons.addEventListener('click', function () { }) } </script>
|
1 2 3 4 5 6 7 8 9
| <script> let buttons = document.querySelectorAll('table button'); let parents = document.querySelector('table'); parents.addEventListener('click', function () { console.log('点击任意子元素都会触发事件...'); }) </script>
|
事件对象中的属性 target 或 srcElement 属性表示真正触发事件的元素,它是一个元素类型的节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <script> const buttons = document.querySelectorAll('table button') const parents = document.querySelector('table') parents.addEventListener('click', function (ev) { if(ev.target.tagName === 'BUTTON') { } }) </script>
|
2.13 其他事件
2.13.1 页面加载事件
加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件
1 2 3
| window.addEventListener('load', function() { })
|
2.13.2 元素滚动事件
滚动条在滚动的时候持续触发的事件
1 2 3
| window.addEventListener('scroll', function() { })
|
2.13.3 页面尺寸事件
会在窗口尺寸改变的时候触发事件
1 2 3
| window.addEventListener('resize', function() { })
|
2.14 元素尺寸与位置
获取元素自身的宽高
offsetWidth
offsetHeight
获取元素的位置
getBoundingClientRect()
**rect.left**:元素的左边距,表示元素左侧到视口左侧的距离
**rect.top**:元素的上边距,表示元素顶部到视口顶部的距离
**rect.right**:元素的右边距,表示元素右侧到视口左侧的距离
**rect.bottom**:元素的下边距,表示元素底部到视口顶部的距离
**rect.width**:元素的宽度
**rect.height**:元素的高度
2.15 日期对象
2.15.1 实例化
1
| const date = new Date('2024-09-26')
|
2.15.2 方法
getFullYear 获取四位年份
getMonth 获取月份,取值为 0 ~ 11
getDate 获取月份中的每一天,不同月份取值也不相同
getDay 获取星期,取值为 0 ~ 6
getHours 获取小时,取值为 0 ~ 23
getMinutes 获取分钟,取值为 0 ~ 59
getSeconds 获取秒,取值为 0 ~ 59
2.15.3 时间戳
时间戳是指1970年01月01日00时00分00秒起至现在的总秒数或毫秒数,它是一种特殊的计量 时间的方式
1 2 3 4 5 6 7 8
| const date = new Date()
console.log(date.getTime())
console.log(+new Date())
console.log(Date.now())
|
2.16 DOM节点
2.16.1 插入节点
createElement 动态创建任意 DOM 节点
cloneNode 复制现有的 DOM 节点,传入参数 true 会复制所有子节点
appendChild 在末尾(结束标签前)插入节点
insertBefore 在父节点中任意子节点之前插入新节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <body> <h3>插入节点</h3> <p>在现有 dom 结构基础上插入新的元素节点</p> <hr> <!-- 普通盒子 --> <div class="box"></div> <!-- 点击按钮向 box 盒子插入节点 --> <button class="btn">插入节点</button> <script> const btn = document.querySelector('.btn') btn.addEventListener('click', function () { const p = document.createElement('p') p.innerText = '创建的新的p标签' p.className = 'info' const p2 = document.querySelector('p').cloneNode(true) p2.style.color = 'red' document.querySelector('.box').appendChild(p) document.querySelector('.box').appendChild(p2) }) </script> </body>
|

2.16.2 删除节点
删除现有的 DOM 节点,也需要关注两个因素:首先由父节点删除子节点,其次是要删除哪个子节点
removeChild 删除节点时一定是由父子关系
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <body> <button>删除节点</button> <ul> <li>HTML</li> <li>CSS</li> <li>Web APIs</li> <script> const btn = document.querySelector('button') btn.addEventListener('click', function () { let ul = document.querySelector('ul') let lis = document.querySelectorAll('li') ul.removeChild(lis[0]) }) </script> </body>
|
2.16.3 查找节点
父子关系
childNodes 获取全部的子节点,回车换行会被认为是空白文本节点
children 只获取元素类型节点
parentNode 获取父节点,以相对位置查找节点
兄弟关系
previousSibling 获取前一个节点,以相对位置查找节点,实际应用中非常灵活
nextSibling 获取后一个节点,以相对位置查找节点,实际应用中非常灵活
2.17 JS组成
ECMAScript: 规定了js基础语法核心知识
Web APIs :
DOM 文档对象模型, 定义了一套操作HTML文档的API
BOM 浏览器对象模型,定义了一套操作浏览器窗口的API
2.18 window对象
2.19 定时器
JavaScript 内置的一个用来让代码延迟执行的函数,叫 setTimeout
延迟函数仅执行一次
延时函数需要等待,所以后面的代码先执行
返回值是一个正整数,表示定时器的编号
清除延迟函数
2.20 location对象
location (地址) 它拆分并保存了 URL 地址的各个组成部分, 它是一个对象
2.21 navigator对象
navigator是对象,该对象下记录了浏览器自身的相关信息
通过 userAgent 检测浏览器的版本及平台
1 2 3 4 5 6 7 8 9 10
| (function () { const userAgent = navigator.userAgent const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/) const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/) if (android || iphone) { location.href = 'http://m.itcast.cn' }})();
|
2.22 history对象
history (历史)是对象,主要管理历史记录, 该对象与浏览器地址栏的操作相对应,如前进、 后退等
2.23 本地存储
本地存储:将数据存储在本地浏览器中
优点:
1、页面刷新或者关闭不丢失数据,实现数据持久化
2、容量较大,sessionStorage和 localStorage 约 5M 左右
2.23.1 localStorage
数据可以长期保留在本地浏览器中,刷新页面和关闭页面,数据也不会丢失
以键值对的形式存储,并且存储的是字符串, 省略了window
2.23.2 sessionStorage
当页面浏览器被关闭时,存储在 sessionStorage 的数据会被清除
1 2 3
| 存储:sessionStorage.setItem(key,value) 获取:sessionStorage.getItem(key) 删除:sessionStorage.removeItem(key)
|
2.23.3 localStorage存储复杂数据类型
将复杂类型转换为JSON字符串
JSON.stringify(复杂数据类型)
JSON字符串:
首先是1个字符串
属性名使用双引号引起来,不能单引号
属性值如果是字符串型也必须双引号
JSON.parse(JSON字符串)
2.24 正则表达式
正则表达式(Regular Expression)是一种字符串匹配的模式(规则)
2.24.1 正则基本使用
定义规则
使用正则
1 2 3 4 5 6 7 8 9
| <script> const str = 'web前端开发' const reg = /web/ console.log(reg.test(str)) console.log(reg.test('java开发')) </script>
|
2.24.2 元字符
元字符:是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能
正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符
如果 ^ 和 $ 在一起,表示必须是精确匹配
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <script> const reg = /^web/ console.log(reg.test('web前端')) console.log(reg.test('前端web')) console.log(reg.test('前端web学习')) console.log(reg.test('we')) const reg1 = /web$/ console.log(reg1.test('web前端')) console.log(reg1.test('前端web')) console.log(reg1.test('前端web学习')) console.log(reg1.test('we')) const reg2 = /^web$/ console.log(reg2.test('web前端')) console.log(reg2.test('前端web')) console.log(reg2.test('前端web学习')) console.log(reg2.test('we')) console.log(reg2.test('web')) console.log(reg2.test('webweb')) </script>
|
量词用来设定某个模式重复次数
逗号左右两侧千万不要出现空格

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| <script> const reg1 = /^w*$/ console.log(reg1.test('')) console.log(reg1.test('w')) console.log(reg1.test('ww')) console.log('-----------------------')
const reg2 = /^w+$/ console.log(reg2.test('')) console.log(reg2.test('w')) console.log(reg2.test('ww')) console.log('-----------------------')
const reg3 = /^w?$/ console.log(reg3.test('')) console.log(reg3.test('w')) console.log(reg3.test('ww')) console.log('-----------------------')
const reg4 = /^w{3}$/ console.log(reg4.test('')) console.log(reg4.test('w')) console.log(reg4.test('ww')) console.log(reg4.test('www')) console.log(reg4.test('wwww')) console.log('-----------------------')
const reg5 = /^w{2,}$/ console.log(reg5.test('')) console.log(reg5.test('w')) console.log(reg5.test('ww')) console.log(reg5.test('www')) console.log('-----------------------')
const reg6 = /^w{2,4}$/ console.log(reg6.test('w')) console.log(reg6.test('ww')) console.log(reg6.test('www')) console.log(reg6.test('wwww')) console.log(reg6.test('wwwww'))
</script>
|
表示字符的范围,定义的规则限定在某个范围,比如只能是英文字母,或者数字等等,用表示范围
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <script> const reg1 = /^[abc]$/ console.log(reg1.test('a')) console.log(reg1.test('b')) console.log(reg1.test('c')) console.log(reg1.test('d')) console.log(reg1.test('ab')) const reg2 = /^[a-z]$/ console.log(reg2.test('a')) console.log(reg2.test('p')) console.log(reg2.test('0')) console.log(reg2.test('A')) const reg3 = /^[a-zA-Z0-9]$/ console.log(reg3.test('B')) console.log(reg3.test('b')) console.log(reg3.test(9)) console.log(reg3.test(',')) const reg4 = /^[a-zA-Z0-9_]{6,16}$/ console.log(reg4.test('abcd1')) console.log(reg4.test('abcd12')) console.log(reg4.test('ABcd12')) console.log(reg4.test('ABcd12_')) const reg5 = /^[^a-z]$/ console.log(reg5.test('a')) console.log(reg5.test('A')) console.log(reg5.test(8)) </script>
|
某些常见模式的简写方式,区分字母和数字
2.25 替换和修饰符
replace 替换方法,可以完成字符的替换
1
| 字符串.replace(/正则表达式/,'替换的文本')
|
修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等
- i 是单词 ignore 的缩写,正则匹配时字母不区分大小写 、
- g 是单词 global 的缩写,匹配所有满足正则表达式的结果
1 2 3 4 5 6 7 8 9 10
| <script> const str = '欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神' const strEnd = str.replace(/前端/g, 'web') console.log(strEnd) </script>
|
2.26 正则插件
2.27 change事件
给input注册 change 事件,值被修改并且失去焦点后触发
- JavaScript诞生于1995年,主要用于处理网页中的前端验证,即检查用户输入的内容是否符合一定的规则
- 由Netscape 和 SUN公司研发
- ECMAScript是JS的标准,简称ES
- 一个完整的JavaScript组成:

二、JS的HelloWorld
1 2 3 4 5
| <script type="text/javascript"> alert("helloworld") document.write("你好~") console.log("这是一行代码"); </script>
|
三、JS编写位置
- 写在
button按钮的onclick属性里面,点击按钮,执行JS代码
1
| <button onclick="console.log('点击按钮')">点击按钮</button>
|
- 写在超链接的href属性中,点击超链接,执行JS代码(不推荐使用)
1 2 3 4
| <a href="javascript:alert('让你点你就点!');">你也点我一下</a> <!-- 没有javascript限定符,点击超链接会显示一串英文 --> <a href="javascript:;">你也点我一下</a> <!-- 点击没有任何反应,只是用于JS处理一些功能 -->
|
- 写在
script标签里面
1 2 3
| <script> console.log("写在script标签里面的JS代码"); </script>
|
- 写在外部的JS文件中,通过
script标签引入(推荐使用)
此时不能在标签内部写代码,即使编写,浏览器也会忽略
1
| <script src="./js/script.js"></script>
|
ES6+
DOM树一共有12种节点类型,常用的有4种:
1、Document类型(document节点)——DOM的“入口点”
2、Element节点(元素节点)——HTML标签,树构建块
3、Text类型(文本节点)——包含文本
4、Comment类型(注释节点)——有时我们可以将一些信息放入其中,它不会显示,但JS可以从DOM中读取它。
JS Tips
DocumentFragment加快DOM渲染速度
DocumentFragment
概念:文档片段接口,表示一个没有父对象的最小文档对象
它被作为一个轻量版的 Document 使用,就像标准的 document 一样,存储由节点(nodes)组成的文档结
构。与 document 相比,最大的区别是它不是真实 DOM 树的一部分,它的变化不会触发 DOM 树的重新渲
染,且不会对性能产生影响。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <ul id="list"> <li>第一项</li> <li>第二项</li> <li>第三项</li> </ul> <script> console.time('执行一万次需要用的时间') let list = document.getElementById('list'); for(let i = 0; i < 10000; i++) { let tempLi = document.createElement('li'); tempLi.innerHTML = i; list.append(tempLi); } //执行一万次需要用的时间: 12.816162109375 ms console.timeEnd('执行一万次需要用的时间') </script> </body> </html>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <ul id="list"> <li>第一项</li> <li>第二项</li> <li>第三项</li> </ul> <script> let list = document.getElementById('list'); let df = document.createDocumentFragment(); for(let i = 0; i < 10000; i++) { let tempLi = document.createElement('li'); tempLi.innerHTML = i; df.append(tempLi); } console.time('执行一万次需要用的时间') list.append(df); //执行一万次需要用的时间: 2.6708984375 ms console.timeEnd('执行一万次需要用的时间') </script> </body> </html>
|
JS计算程序运行时间
方法一
1 2 3 4 5
| console.time('执行一万次需要用的时间') for(let i=0;i<10000;i++){ } console.timeEnd('执行一万次需要用的时间')
|
JSON和XML之间的区别:
1、JSON是JavaScript Object Notation;XML是可扩展标记语言。
2、JSON是基于JavaScript语言;XML源自SGML。
3、JSON是一种表示对象的方式;XML是一种标记语言,使用标记结构来表示数据项。
4、JSON不提供对命名空间的任何支持;XML支持名称空间。
5、JSON支持数组;XML不支持数组。
6、XML的文件相对难以阅读和解释;与XML相比,JSON的文件非常易于阅读。
7、JSON不使用结束标记;XML有开始和结束标签。
8、JSON的安全性较低;XML比JSON更安全。
9、JSON不支持注释;XML支持注释。
10、JSON仅支持UTF-8编码;XML支持各种编码。
Domtree的根节点是document
https://www.cnblogs.com/cangqinglang/p/8963557.html
如果文档包含框架( 或