JavaScript介绍
什么是JavaScript
JavaScript是运行在浏览器中的一种脚本语言,它主要用于与HTML页面进行交互
JavaScript的组成部分
名称 | 说明 |
---|---|
ECMAScript | JavaScript的标准,定义了JavaScript的核心内容 |
BOM | Browser Objcet Model,浏览器对象模型,用于操纵浏览器对象 |
DOM | Document Object Model,文档对象模型,用于操纵HTML文档对象 |
引入JavaScript
内部引入方式
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<!-- HTML代码块 -->
<script>
// JavaScript代码块
</script>
</body>
</html>
外部引入方式
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8"/>
<script src="js文件路径"></script>
</head>
<body>
<!-- HTML代码块 -->
<script src="js文件路径"></script>
</body>
</html>
嵌入引入方式
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<input type="button" value="提交" onclick="alert(this.value)"/>
</body>
</html>
ES基础语法
控制台输出
console.log("Hello World!")
console.log("Hello","World","!")
注释
单行注释
// 注释内容
多行注释
/*
注释内容
*/
变量
声明变量
var 变量名;
var uname
var 变量1,变量2,...
var uname,sex
var 变量名 = 初始值
var uname = '张三'
声明区块变量
let 变量名
let uname = '张三'
声明常量
常量声明时必须有初始值,不能二次修改
const 常量名 = 常量值
const PI = 3.14
变量使用
var
和let
声明的变量,均有初始值undefined
let uname
console.log(uname) // undefined
let uname = '张三'
console.log(uname) // 张三
当使用一个没有声明的变量时,会报错
console.log(sex) // 报错
var
声明的变量,可以先使用后声明
console.log(sex) // undefined
var sex = 20
let
声明的变量,必须先声明后使用
console.log(sex) // 报错
let sex = 20
在代码块中,使用var
声明的变量可以在代码块的外部使用
{
var sex = 20
}
{
console.log(sex) // 20
}
在代码块中,使用let
声明的变量只能在声明变量的代码块中使用
{
let sex = 20
}
{
console.log(sex) // 报错
}
使用const
声明的常量不能被二次赋值
const PI = 3.14
PI = 3.1415 // 报错
数据类型
基本数据类型
字符串
console.log(typeof('张三')) // string
console.log(typeof("张三")) // string
数值
Infinity
当被除数为 0
是,则会出现 Infinity
console.log(typeof(20)) // number
console.log(typeof(3.14)) // number
console.log(typeof(Infinity)) // number
布尔
布尔的本质是整数
true
的值为1
false
的值为0
console.log(typeof(true)) // boolean
console.log(typeof(false)) // boolean
undefined
console.log(typeof(undefined)) // undefined
对象
console.log(typeof (null)) // object
var v = []
console.log(typeof (v)) // object
var v = new Object()
console.log(typeof (v)) // object
var v = {}
console.log(typeof (v)) // object
函数
function f (){}
console.log(typeof (f)) // function
var f = function(){}
console.log(typeof (f)) // function
数据类型转换
隐式转换
一般情况下,变量的类型会根据值的变化而变化
var x = 10
console.log(typeof(x)) // number
x = '张三'
console.log(typeof(x)) // string
当字符串与数字进行运算时,数字会被转成字符串
var x = 10
var y = '张三的年龄:' + x
console.log(y) // 张三的年龄:10
字符串转为数字
将字符串转为整数
var x = '3.14'
console.log(parseInt(x)+1) // 4
var x = '3.14是圆周率'
console.log(parseInt(x)+1) // 4
var x = '圆周率是3.14'
console.log(parseInt(x)+1) // NaN
var x = '3'
console.log((+x)+1) // 4
将字符串转为浮点数
var x = '3'
console.log(parseFloat(x)+1) // 4
var x = '3.14'
console.log(parseFloat(x)+1) // 4.140000000000001
var x = '3.14是圆周率'
console.log(parseFloat(x)+1) // 4.140000000000001
var x = '3.14'
console.log((+x)+1) // 4.140000000000001
var x = '3.14是圆周率'
console.log((+x)+1) // NaN
判断是否为数值类型
console.log(isNaN('a')) // true
console.log(isNaN(false)) // false
console.log(isNaN(10)) // false
console.log(isNaN('10')) // false
运算符
赋值运算符
赋值
x = y
加法赋值
x += y // x = x + y
减法赋值
x -= y // x = x - y
乘法赋值
x *= y // x = x * y
除法赋值
x /= y // x = x / y
求余赋值
x %=y // x = x % y
求幂赋值
x **= y // x = x ** y
算数运算符
加法
x + y
减法
x - y
乘法
x * y
除法
x / y
求幂
y个x相乘
x ** y
自增
x++ // x = x + 1
自减
x-- // x = x - 1
比较运算符
值等于
只判断值,不判断类型
x == y
全等于
即判断值,也判断类型
x === y
值不等于
只判断值,不判断类型
x != y
不全等于
即判断值,也判断类型
x !== y
大于
x > y
小于
x < y
大于等于
x >= y
小于等于
x <= y
逻辑运算符
逻辑运算的结果只有两个:true
或false
逻辑与
一假则假
x && y
逻辑或
一真则真
x || y
逻辑非
非真即假
!x
三元运算符
x ? y : z
不同类型之间的加法运算
数值与数值相加
number + number = number
var x = 1
var y = 2
console.log(x + y) // 3
数值与布尔相加
number + boolean = number
true == 1
false == 0
var x = true
var y = 1
console.log(x + y) // 2
数值与字符串相加
number + string = string
var x = 10
var y = 'Hello'
console.log(x + y) // 10Hello
布尔与字符串相加
boolean + string = string
var x = true
var x = 'Hello'
console.log(x + y) // trueHello
运算符优先级
- () > 一元运算符 > 算术运算符 > 比较运算符 > 逻辑运算符 > 赋值运算符
- ++或-- > *或/或% > +或-
- ! > && > ||
语句块
{
// 代码块
}
控制流
判断分支
if…else
if(条件){
// 代码块
}else if(条件){
// 代码块
}else{
// 代码块
}
switch
switch(表达式){
case 常量:
// 代码块
[break]
case 常量:
// 代码块
[break]
default:
// 代码块
[break]
}
循环迭代
for
固定次数循环
for([初始化表达式];[条件];[更新表达式]){
// 代码块
}
while
非固定次数的循环
while(条件){
// 代码块
}
do…while
至少执行一次的循环
do{
// 代码块
}while(条件);
break
跳出当前循环
for (x = 1; x <= 5; x++) {
for (y = 1; y <= 100; y++) {
console.log('x=', x, 'y=', y)
if (y == 2) {
break // 仅仅跳出内层循环,无法跳出外层循环
}
}
}
跳出到指定位置,退出循环
out:
for (x = 1; x <= 5; x++) {
for (y = 1; y <= 100; y++) {
console.log('x=', x, 'y=', y)
if (y == 2) {
break out // 直接跳转到 out 位置,跳过循环继续执行
}
}
}
continue
停止本次循环,继续下次循环
for (x = 1; x <= 10; x++) {
if (x % 2 == 0) {
continue // 直接跳转到 'x++' 继续执行
}
console.log('x=', x)
}
跳转到指定位置,继续循环
into:
for (x = 1; x <= 5; x++) {
for (y = 1; y <= 100; y++) {
console.log('x=', x, 'y=', y)
if (y == 2) {
continue into // 跳转到 into 位置,继续进入循环
}
}
}
for…in
let x = ['a','b','c','d']
for (i in x) {
console.log(x[i])
}
for…of
let x = ['a','b','c','d']
for (i of x) {
console.log(i)
}
异常处理
throw
抛出异常,并自定义抛出信息
var x = 10
var y = 0
if(y == 0){
throw '被除数不能为 0'
}else{
console.log(x / y)
}
try…catch…finally
尝试捕获异常,如果出现异常则进行异常处理,finally
块无论是否出现异常都会被执行
try{
console.log(x)
}catch(e){
console.log(e)
}finally{
console.log('finally')
}
Promise
用于表示一个异步操作的最终完成 (或失败), 及其结果值.
function f(flag){
return new Promise(function(resolve,reject){
if(flag){
resolve('成功')
}else{
reject('失败')
}
})
}
x = true
f(x).then(function(res){
console.log(res) // x == true : 成功
}).catch(function(res){
console.log(res) // x == false : 失败
})
函数
函数声明
无参函数
无返回值的函数
function 函数名(){
// ...
}
有返回值的函数
function 函数名(){
// ...
return 返回值
}
带参函数
带有固定数量的参数
function 函数名(形参,形参,...){
// ...
}
带有不固定数量的参数
function 函数名(...形参){
// ...
}
带有默认值的参数
function 函数名(形参=默认值){
// ...
}
闭包函数(匿名函数)
let 变量名 = function(){
// ...
}
箭头函数
无参箭头函数
let 变量名 = ()=>{
// ...
}
有单个参数的箭头函数
let 变量名 = 形参=>{
// ...
}
有多个参数的箭头函数
let 变量名 = (形参,形参,...)=>{
// ...
}
方法体内只有一句话
let x = v => v + 10
let y = x(1)
console.log(y) // 11
函数调用
调用无参函数
function f(){
console.log('This is function')
}
f()
调用固定参数的函数
function f(x,y){
console.log(x+y)
}
f(1,2)
调用非固定参数的函数
function f(...x){
let y = 0
for(i of x){
y += x
}
console.log(y)
}
f(1,2,3,4,5)
调用带返回值的函数
function f(x,y){
return x + y
}
let z = f(1,2)
console.log(z)
调用闭包函数
let f = function(){
console.log('This is function')
}
f()
setTimeOut(function(){
console.log('This is function')
},1)
回调函数
function f(x,y,cb){
let z = x + y
cb(z)
}
f(1,2,function(res){
console.log(res)
})
递归函数
函数体内调用自己
必须要有退出条件
let x = [1, 4, 2, 7, -1, 2, 6, 4]
let y = 0
function f(i) {
if(x[i]<0){
return y
}
y += x[i]
return f(++i)
}
let z = f(0)
console.log(z)
函数调用注意事项
如果方法调用和方法声明在同一个<script>
块中,则可以先调用后声明
<script>
console.log(fun(1,2));
function fun(i,j){
return i+j;
}
</script>
如果方法调用和方法声明不在同一个<script>
块中,则必须要先声明后调用
<script>
function fun(i,j){
return i+j;
}
</script>
<script>
document.write(fun(1,2));
</script>
如果尝试接收一个无返回值的函数,则得到的返回值为undefined
<script>
function fun(x){
document.write(x);
}
var r = fun(10);
document.write(r);
</script>
解构
使用结构赋值
解构数组
let [x,y] = [1,2]
console.log(x,y) // 1 2
解构对象
变量名要与对象属性名保持一致
let {name,sex} = {name:'张三',sex:20}
console.log(name,sex) // 张三 20
默认值
let {name,sex=10} = {name:'张三'}
console.log(name,sex) // 张三 10
忽略值
let [x,,y] = [1,2,3]
console.log(x,y) // 1 3
将剩余的值赋给一个变量
let [x,y,...z] = [1,2,3,4,5]
console.log(x,y,z) // 1 2 [3, 4, 5]
展开语法
展开数组
let x = [1,2,3,4]
console.log(...x) // 1 2 3 4
数组拷贝
let x = [1,2,3,4]
let y = [...x,5,6,7]
console.log(y) // [1, 2, 3, 4, 5, 6, 7]
函数调用
function calc(x,y,z){
console.log(x + y + z)
}
let p = [1,2,3]
calc(...p) // 6
展开对象
对象展开后只能用于创建另一个对象
let x = {name:'张三',age:20}
let y = {sex:'男'}
console.log({...x,...y}) // {name: "张三", age: 20, sex: "男"}
对象
在javascript中,万物皆对象,所有的对象都继承于顶级对象Object
字面量对象
一次只能创建一个对象
let person = {
name:'张三',
age:20
}
console.log(person.name,person.age)
构造函数
可以构建多个对象,但是每次构建对象时,都会拷贝构造函数里面的所有成员
无参构造函数
function Person(){
this.name = '张三'
this.age = 20
this.say = function(){
console.log(`我叫${this.name},今年${this.age}岁了`)
}
}
let p = new Person()
p.say()
带参构造函数
function Person(name,age){
this.name = name
this.age = age
this.say = function(){
console.log(`我叫${this.name},今年${this.age}岁了`)
}
}
let p = new Person('张三',20)
p.say()
对象继承
function Person(name,age){
this.name = name
this.age = age
this.say = function(){
console.log(`我叫${this.name},今年${this.age}岁了`)
}
}
function Employee(name,age){
Person.call(this,name,age)
}
let e = new Employee('张三',20)
e.say()
原型
在javascript中,每个对象都有一个原型,每个原型也有原型,最顶端的原型为null,null没有原型
使用原型可以构建多个对象,每个对象都拥有独立的属性,但方法会被所有对象共享
使用原型创建的对象,无法在构建对象时对属性进行初始化
function Person() { }
Person.prototype.name = '张三'
Person.prototype.age = 20
Person.prototype.say = function () {
console.log(`我叫${this.name},今年${this.age}岁了`)
}
let p = new Person()
p.say()
构造函数加原型
构造函数可以为属性进行初始化,原型可以是每个对象都共享方法
function Person(name,age) {
this.name = name
this.age = age
}
Person.prototype.say = function () {
console.log(`我叫${this.name},今年${this.age}岁了`)
}
let p = new Person('张三','李四')
p.say()
原型链
原型链解决了对象间的继承问题,每个对象都可以作为另一个对象的原型
function Person(name,age) {
this.name = name
this.age = age
}
Person.prototype.say = function () {
console.log(`我叫${this.name},今年${this.age}岁了`)
}
function Employee(name,age){
Person.call(this,name,age)
}
Employee.prototype = new Person()
let e = new Employee('张三',20)
e.say()
实例所属
判断实例是否属于某个构造函数
function Person() { }
function Employee() { }
Employee.prototype = new Person()
let e = new Employee()
console.log(e instanceof Employee) // true
console.log(e instanceof Person) // true
判断实例是否来自于某个构造函数
function Person() { }
function Employee() { }
Employee.prototype = new Person()
let e = new Employee()
console.log(e.constructor == Employee) // false
console.log(e.constructor == Person) // true
类
JavaScript中的类与java的不同,只是语法相近而已,底层还是基于原型实现的
创建类
class Person{
// ...
}
let p = new Person()
构造方法
无参构造
class Person{
constructor(){
this.name = '张三'
this.age = 20
}
}
let p = new Person()
console.log(p.name,p.age) // 张三 20
有参构造
class Person{
constructor(name,age){
this.name = name
this.age = age
}
}
let p = new Person('张三',20)
console.log(p.name,p.age) // 张三 20
带默认值的有参构造
class Person{
constructor(name,age){
this.name = name || '匿名'
this.age = age || 0
}
}
let p = new Person()
console.log(p.name,p.age) // 匿名 0
实例方法
class Person{
constructor(name,age){
this.name = name || '匿名'
this.age = age || 0
}
say(){
console.log(`我叫${this.name},今年${this.age}岁了!`)
}
}
let p = new Person('张三',20)
p.say() // 我叫张三,今年20岁了!
静态方法
静态方法只能由类直接调用,实例对象无法调用
静态方法中不能调用实例成员
class Person{
static say(name,age){
console.log(`我叫${name},今年${age}岁了!`)
}
}
Person.say('张三',20) // 我叫张三,今年20岁了!
类的继承
class Person{
constructor(name,age){
this.name = name || '匿名'
this.age = age || 0
}
say(){
console.log(`我叫${this.name},今年${this.age}岁了!`)
}
}
class Employee extends Person{}
let e = new Employee('张三',20)
e.say() // 我叫张三,今年20岁了!
调用父级的构造方法
class Person{
constructor(name,age){
this.name = name || '匿名'
this.age = age || 0
}
say(){
console.log(`我叫${this.name},今年${this.age}岁了!`)
}
}
class Employee extends Person{
constructor(name,age,sex){
super(name,age)
this.sex = sex || '未知'
}
}
let e = new Employee('张三',20,'男')
e.say()
调用父级的方法
class Person{
constructor(name,age){
this.name = name || '匿名'
this.age = age || 0
}
say(){
console.log(`我叫${this.name},今年${this.age}岁了!`)
}
}
class Employee extends Person{
constructor(name,age,sex){
super(name,age)
this.sex = sex || '未知'
}
say(){
super.say()
console.log(`我是${this.sex}孩子`)
}
}
let e = new Employee('张三',20,'男')
e.say()
模块
模块可以是一个js脚本,也可以由多个js脚本组成
创建模块
// modules/index.js
let uname = '张三'
function say(){
console.log('Hello!!')
}
导出模块成员
单独导出
// modules/person.js
export let uname = '张三'
export function say(){
console.log('Hello!!')
}
统一导出
// modules/person.js
let uname = '张三'
function say(){
console.log('Hello!!')
}
export{uname,say}
导入模块
<!-- index.html -->
<script type="module">
import {uname,say} from './person.js'
console.log(uname)
say()
</script>
定义别名
导出时定义别名
// modules/person.js
let uname = '张三'
function say(){
console.log('Hello!!')2
}
export{uname as u,say as s}
<!-- index.html -->
<script type="module">
import {u,s} from './person.js'
console.log(u)
s()
</script>
导入时定义别名
// modules/person.js
let uname = '张三'
function say(){
console.log('Hello!!')
}
export{uname,say}
<!-- index.html -->
<script type="module">
import {uname as u,say as s} from './person.js'
console.log(u)
s()
</script>
默认导出
// modules/person.js
let uname = '张三'
function say(){
console.log('Hello!!')
}
export default{uname,say}
<!-- index.html -->
<script type="module">
import person from './person.js'
console.log(person.uname)
person.say()
</script>
ES内置对象
数组
创建数组
new Array(n)
var arr = new Array(5)
Array(v1,v2,…)`
var arr = Array('a','b',3,4)
[v1,v2,...]
var arr = ['a','b',3,4]
填充数组
var arr = new Array(5)
arr[0] = 'a'
arr[1] = 'b'
arr[2] = 'c'
arr[3] = 'd'
数组操作
获取数组中的某个元素的值
var arr = ['a','b','c','d']
console.log(arr[2]) // c
循环遍历数组
var arr = ['a','b','c','d']
for(i in arr){
console.log(arr[i])
}
var arr = ['a','b','c','d']
for(i of arr){
console.log(i)
}
修改数组中的某个元素的值
var arr = ['a','b','c','d']
console.log(arr[2]) // c
arr[2] = 'e'
console.log(arr[2]) // e
删除数组中的某个元素
var arr = ['a','b','c','d']
console.log(arr[2]) // c
delete arr[2]
console.log(arr[2]) // undefined
数组属性
查看数组长度
var arr = ['a','b','c','d']
console.log(arr.length)
数组方法
连接两个数组
x.concat(y) ==> z
var x = [1,2,3]
var y = ['a','b','c']
var z = x.concat(y)
console.log(z) // [1, 2, 3, "a", "b", "c"]
将数组转成字符串
x.join(y) ==> z
var x = [1,2,3]
var y = '-'
var z = x.join(y)
console.log(z) // 1-2-3
插入元素
在数组末尾添加一个或多个元素
x.push(v1,v2,...)
var x = [1,2,3]
x.push('a','b')
console.log(x) // [1, 2, 3, "a", "b"]
在数组开头添加一个或多个元素
x.unshift(v1,v2,...)
var x = [1,2,3]
x.unshift('a','b')
console.log(x) // [ "a", "b", 1, 2, 3]
移除元素
移除数组的最后一个元素
x.pop()
var x = [1,2,3]
x.pop()
console.log(x) // [1, 2]
移除数组的第一个元素
x.shift()
var x = [1,2,3]
x.shift()
console.log(x) // [2, 3]
从数组提取一个片段,并作为一个新数组返回
x.slice(start,end)
var x = [1,2,3,4,5,6]
var y = x.slice(2,4)
console.log(y) // [3, 4]
删除指定范围的元素,并用新元素替换
x.splice(start)
删除下标为3之后的所有元素
var x = ['a','b','c','d','e','f']
x.splice(3)
console.log(x) // ["a", "b", "c"]
x.splice(start,size)
删除下标为2之后的3个元素
var x = ['a','b','c','d','e','f']
x.splice(2,3)
console.log(x) // ["a", "b", "f"]
x.splice(start,size,v1,v2,...)
删除指定范围的元素,并用新元素替换
var x = ['a','b','c','d','e','f']
x.splice(2,3,'x','y','z')
console.log(x) // ["a", "b", "x", "y", "z", "f"]
颠倒数组元素的顺序
x.reverse()
var x = [3,1,6,7,2,4,5]
x.reverse()
console.log(x) // [5, 4, 2, 7, 6, 1, 3]
数组升序排序
x.sort()
var x = [3, 1, 6, 7, 2, 4, 5]
x.sort()
console.log(x) // [1, 2, 3, 4, 5, 6, 7]
在数组中搜索元素
从下标为0的元素开始搜索
x.indexOf(searchEle) ==> index
var x = ['b','a','e','d','a','f']
var z = x.indexOf('a')
console.log(z) // 1
从下标为2的元素开始搜索
x.indexOf(searchEle,fromIndex) ==> index
var x = ['b','a','e','d','a','f']
var z = x.indexOf('a',2)
console.log(z) // 4
从最后一个元素向前搜索
x.lastIndexOf(searchEle) ==> index
var x = ['b','a','e','d','a','f']
var z = x.lastIndexOf('a')
console.log(z) // 4
遍历数组
x.forEach(callback(element,index))
var x = ['b','a','e','d','a','f']
x.forEach(function(e,i){
console.log(i,e)
})
遍历并修改数组的元素值
x.map(callback(element,index)) ==> z
var x = ['b','a','e','d','a','f']
var y = x.map(function(e,i){
return e.toUpperCase()
})
console.log(y) // ["B", "A", "E", "D", "A", "F"]
数组过滤
x.filter(element,index) ==> z
var x = [1,7,4,2,9,8,3,5,6]
var y = x.filter(function(e,i){
return e > 5
})
console.log(y) // [7, 9, 8, 6]
集合
集合里面的值都是唯一的,不可重复
创建集合
创建空集合
let x = new Set()
console.log(x) // Set(0) {}
创建非空集合
let x = new Set([1,2,3,4])
console.log(x) // Set(4) {1, 2, 3, 4}
集合属性
查看集合长度
let x = new Set([1,2,3,4])
console.log(x.size) // 4
集合方法
添加元素
let x = new Set()
x.add(1)
x.add(2)
console.log(x) // Set(2) {1, 2}
删除元素
let x = new Set(['a','b','c','d'])
x.delete('b')
console.log(x) // Set(3) {"a", "c", "d"}
清空集合
let x = new Set(['a','b','c','d'])
x.clear()
console.log(x) // Set(0) {}
判断给定的值是否在集合中
let x = new Set(['a','b','c','d'])
console.log(x.has('c')) // true
遍历集合
let x = new Set(['a','b','c','d'])
x.forEach(function(e){
console.log(e)
})
Map
键值对结构,键不可重复,值可以重复
创建Map
创建空Map
let x = new Map()
console.log(x) // Map(0) {}
创建非空Map
let x = new Map(
[
['张三', 20],
['李四', 18],
['王五', 19]
]
)
console.log(x) // Map(3) {"张三" => 20, "李四" => 18, "王五" => 19}
Map属性
获取Map长度
let x = new Map([['张三', 20],['李四', 18],['王五', 19]])
console.log(x.size) // 3
Map方法
添加元素
let x = new Map([['张三', 20],['李四', 18],['王五', 19]])
x.set('赵六',22)
console.log(x) // Map(4) {"张三" => 20, "李四" => 18, "王五" => 19, "赵六" => 22}
获取给定key的值
let x = new Map([['张三', 20],['李四', 18],['王五', 19]])
console.log(x.get('李四')) // 18
修改元素
let x = new Map([['张三', 20],['李四', 18],['王五', 19]])
x.set('李四',22)
console.log(x) // Map(3) {"张三" => 20, "李四" => 22, "王五" => 19}
删除元素
let x = new Map([['张三', 20],['李四', 18],['王五', 19]])
x.delete('李四')
console.log(x) // Map(2) {"张三" => 20, "王五" => 19}
清空Map
let x = new Map([['张三', 20],['李四', 18],['王五', 19]])
x.clear()
console.log(x) // Map(0) {}
遍历Map
let x = new Map([['张三', 20],['李四', 18],['王五', 19]])
x.forEach(function(v,k){
console.log(k,v)
})
查询给定的key是否存在
let x = new Map([['张三', 20],['李四', 18],['王五', 19]])
console.log(x.has('李四')) // true
获取所有的key
let x = new Map([['张三', 20],['李四', 18],['王五', 19]])
console.log(x.keys()) // MapIterator {"张三", "李四", "王五"}
获取所有的value
let x = new Map([['张三', 20],['李四', 18],['王五', 19]])
console.log(x.values()) // MapIterator {20, 18, 19}
字符串
创建字符串
双引号形式
console.log("This is string")
单引号形式
console.log('This is string')
多行形式的字符串
使用+
拼接
console.log('This is'+
'string') // This is string
使用 \
拼接
console.log('This is \
string') // This is string
使用`` `包裹字符串
console.log(`This is
string`) // This is
// string
模板字面量
let name = '张三'
let sex = 20
let x = `${name}今年${sex}岁了`
console.log(x) // 张三今年20岁了
字符串对象
let x = new String('This is string')
console.log(x) // String {"This is string"}
字符串属性
查看字符串长度
let x = 'This is string'
console.log(x.length) // 14
字符串方法
从字符串中获取单个字符
x.charAt(index)
let x = 'This is string'
console.log(x.charAt(2)) // i
x[index]
let x = 'This is string'
console.log(x[2]) // i
拼接字符串
x.concat(y)
let x = 'This is '
let y = 'string'
let z = x.concat(y)
console.log(z) // This is string
x + y
let x = 'This is '
let y = 'string'
let z = x + y
console.log(z) // This is string
判断是否包含某个字符串
x.includes(y)
let x = 'This is string'
let y = 'str'
let z = x.includes(y)
console.log(z) // true
判断是否以某个字符串结尾
x.endsWith(y)
let x = 'This is string'
let y = 'ing'
let z = x.endsWith(y)
console.log(z) // true
判断是否以某个字符串开头**
x.startsWith(y)
let x = 'This is string'
let y = 'This'
let z = x.startsWith(y)
console.log(z) // true
查找字符串
查找某个字符串的位置,查到了返回索引,没查到返回-1
x.indexOf(y)
let x = 'This is string'
let y = 'is'
let z = x.indexOf(y)
console.log(z) // 2
使用则匹配,返回匹配后的结果数组
x.match(y)
let x = '12345@163.com'
let y = /\d+/g
let z = x.match(y)
console.log(z) // ["12345", "163"]
使用正则或字符串搜索,返回索引,如果没搜索到,返回-1
x.search(y)
let x = '12345@163.com'
let y = '163'
console.log(x.search(y)) // 6
字符串替换
x.replace(y,z)
let x = '12345@163.com'
let y = '163'
let z = 'qq'
console.log(x.replace(y,z)) //12345@qq.com
截取字符串
x.slice(start,end)
let x = '12345@163.com'
console.log(x.slice(2,5)) // 345
x.substring(start,end)
let x = '12345@163.com'
console.log(x.substring(2,5)) // 345
分割字符串
x.split(y)
let x = '12345@163.com'
console.log(x.split('@')) // ["12345", "163.com"]
英文字母大小写转换
转成小写
x.toLocaleLowerCase()
let x = 'This Is String'
console.log(x.toLocaleLowerCase()) // this is string
x.toLowerCase()
let x = 'This Is String'
console.log(x.toLowerCase()) // this is string
转成大写
x.toLocaleUpperCase()
let x = 'This Is String'
console.log(x.toLocaleUpperCase()) // THIS IS STRING
x.toUpperCase()
let x = 'This Is String'
console.log(x.toUpperCase()) // THIS IS STRING
去除首尾空格
x.trim()
let x = ' This Is String '
console.log(x.trim()) // This Is String
任何类型的数据转成字符串
x.toString()
let x = 100
let y = x.toString()
console.log(typeof y) // string
String(x)
let x = 100
let y = String(x)
console.log(typeof y) // string
数字
创建数字
字面量创建
let x = 10
console.log(x) // 10
构造函数创建
let x = new Number(10)
console.log(x) // Number {10}
数字方法
判断给定的值是否为非数字
Number.isNaN(x)
或 isNaN(x)
console.log(Number.isNaN('a')) // true
console.log(isNaN(10)) // false
判断给定的值是否为整数
Number.isInteger(x)
console.log(Number.isInteger(10)) // true
console.log(Number.isInteger(10.0)) // true
console.log(Number.isInteger(3.14)) // false
将给定的值转为浮点数
Number.parseFloat(x)
或 parseFloat(x)
let x = '50'
let y = Number.parseFloat(x)
console.log(typeof y) // number
let x = '50'
let y = parseFloat(x)
console.log(typeof y) // number
将给定的值转为整数
Number.parseInt(x)
或 parseInt(x)
let x = '50'
let y = Number.parseInt(x)
console.log(typeof y) // number
let x = '50'
let y = parseInt(x)
console.log(typeof y) // number
数学
数学属性
圆周率
console.log(Math.PI) // 3.141592653589793
数学方法
绝对值
console.log(Math.abs(-10)) // 10
向上取整
console.log(Math.ceil(12.01)) // 13
向下取整
console.log(Math.floor(12.99)) // 12
返回最大值
console.log(Math.max(5,2,6,9,1,7)) // 9
返回最小值
console.log(Math.min(5,2,6,9,1,7)) // 1
产生0~1的随机数
console.log(Math.random()) // 0.544536372532334
四舍五入
console.log(Math.round(12.5)) // 13
console.log(Math.round(12.4)) // 12
返回一个数的整数部分
console.log(Math.trunc(12.9)) // 12
返回指定的小数位
console.log(Math.PI.toFixed(2))
日期时间
创建日期对象
new Date()
let x = new Date()
console.log(x) // Sat Sep 19 2020 17:02:43 GMT+0800 (中国标准时间)
new Date('yyyy-MM-ddThh:mm:ss')
let x = new Date('1900-10-01T12:20:03')
console.log(x) // Mon Oct 01 1900 12:20:03 GMT+0805 (中国标准时间)
new Date(year,monthIndex,day,hours,minutes,seconds)
monthIndex
表示月份的整数值,从 0(1月)到 11(12月)
let x = new Date(2000,10,1,13,20,5)
console.log(x) // Wed Nov 01 2000 13:20:05 GMT+0800 (中国标准时间)
日期时间方法
获取时间戳
返回自 1970-1-1 00:00:00 UTC(世界标准时间)至今所经过的毫秒数
console.log(Date.now()) // 1600506934200
解析一个表示日期的字符串,并返回从 1970-1-1 00:00:00 所经过的毫秒数。
console.log(Date.parse('2020-10-10T11:11:05')) // 1602299465000
Date.UTC(year,monthIndex,day,hours,minutes,seconds)
console.log(Date.UTC(2020, 10, 10, 11, 11, 3)) // 1605006663000
获取年份
let x = new Date('2020-09-19T17:22:10')
console.log(x.getFullYear()) // 2020
获取月份
0
表示一月,1
表示二月,2
表示三月,以此类推
let x = new Date('2020-09-19T17:22:10')
console.log(x.getMonth()) // 8
获取当月的第几天
let x = new Date('2020-09-19T17:22:10')
console.log(x.getDate()) // 19
获取小时数
let x = new Date('2020-09-19T17:22:10')
console.log(x.getHours()) // 17
获取分钟数
let x = new Date('2020-09-19T17:22:10')
console.log(x.getMinutes()) // 22
获取秒数
let x = new Date('2020-09-19T17:22:10')
console.log(x.getSeconds()) // 10
获取毫秒数
let x = new Date('2020-09-19T17:22:10.123')
console.log(x.getMilliseconds()) // 123
获取周几
0
表示周日,1
表示周一,2
表示周二,以此类推
let x = new Date('2020-09-19T17:22:10')
console.log(x.getDay()) // 6
获取时间戳
返回从1970-1-1 00:00:00 UTC(协调世界时)到该日期经过的毫秒数
let x = new Date('2020-09-19T17:22:10.123')
console.log(x.getTime()) // 1600507330123
将时间转成字符串
let x = new Date('2020-09-19T17:22:10.123')
console.log(x.toDateString()) // Sat Sep 19 2020
let x = new Date('2020-09-19T17:22:10.123')
console.log(x.toLocaleString()) // 2020/9/19 下午5:22:10
let x = new Date('2020-09-19T17:22:10.123')
console.log(x.toLocaleDateString()) // 2020/9/19
let x = new Date('2020-09-19T17:22:10.123')
console.log(x.toLocaleTimeString()) // 下午5:22:10
JSON
创建JSON
let x = {name:'张三',sex:20}
console.log(x) // {name: "张三", sex: 20}
JSON方法
将JSON转为字符串
let x = {name:'张三',sex:20}
console.log(JSON.stringify(x)) // {"name":"张三","sex":20}
将字符串转为JSON
let x = '{"name":"张三","sex":20}'
console.log(JSON.parse(x)) // {name: "张三", sex: 20}
正则表达式
创建正则表达式
/pattern/flags
let x = /ab+c/i
new RegExp(pattern,flags)
let x = new RegExp('ab+c','i')
let x = new RegExp(/ab+c/,'i')
正则表达式的标记
标记 | 说明 |
---|---|
g | 全局匹配 |
i | 忽略大小写 |
m | 多行匹配 |
正则表达式方法
搜索匹配
在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null
let x = '12345@163.com'
let y = new RegExp(/\d+/)
console.log(y.exec(x)) // ["12345", index: 0, input: "12345@163.com", groups: undefined]
执行一个检索,用来查看正则表达式与指定的字符串是否匹配,如果匹配返回true,否则返回false
let x = '12345@163.com'
let y = new RegExp(/\d+/)
console.log(y.test(x)) // true
正则表达式符号
符号 | 说明 |
---|---|
/…/ | 代表一个模式的开始和结束 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
s | 任何空白字符 |
S | 任何非空白字符 |
d | 匹配一个数字字符,等价于[0-9] |
D | 除了数字之外的任何字符,等价于[^0-9] |
w | 匹配一个数字、下划线或字母字符,等价于[A-Za-z0-9_] |
W | 任何非单字字符,等价于[^a-zA-z0-9_] |
. | 除了换行符之外的任意字符 |
() | 对数据进行分组 |
[] | 在范围内,例如:[357]只能取3或5或7,[3-7]3到7范围内的一个值 |
[^] | 不在范围内 |
{n} | 匹配前一项n次 |
{n,} | 匹配前一项n次,或者多次 |
{n,m} | 匹配前一项至少n次,但是不能超过m次 |
* | 匹配前一项0次或多次,等价于{0,} |
+ | 匹配前一项1次或多次,等价于{1,} |
? | 匹配前一项0次或1次,也就是说前一项是可选的,等价于{0,1} |
| | 或者,例如:135d{8}|189d{8} 135或189开头的电话号码 |
DOM文档
页面
页面属性
获取来源页面的URL
console.log(document.referrer)
获取当前文档的字符集
console.log(document.characterSet) // UTF-8
获取当前文档的标题
console.log(document.title)
页面状态
判断当前页面是否隐藏
console.log(document.hidden) // false
获取当前页面的状态
状态 | 说明 |
---|---|
visible | 页面可见 |
hidden | 页面隐藏 |
prerender | 页面正在渲染 |
console.log(document.visibilityState)
获取当前文档的加载状态
状态 | 说明 |
---|---|
loading | 正在加载 |
interactive | 文档已被解析,但诸如图片、样式和框架之类的子元素仍在加载 |
complete | 加载完成 |
console.log(document.readyState) // loading
节点
创建节点
创建标签
document.createElement('nodeName')
let a = document.createElement('a')
console.log(a) // <a></a>
创建属性
document.createAttribute('attrName')
attr.textContent = 'attrValue'
let href = document.createAttribute('href')
href.textContent = 'http://localhost'
console.log(href) // href = "http://localhost"
创建文本
document.createTextNode('text')
let text = document.createTextNode('超链接')
console.log(text) // "超链接"
创建注释
let comm = document.createComment('这是注释')
console.log(comm) // <!--这是注释-->
获取节点
获取当前文档的html元素
let html = document.documentElement)
获取当前文档的body元素
let body = document.body
获取当前文档中的head元素
let head = document.head
获取当前文档中所有的表单元素
let forms = document.forms
获取当前文档中所有的img元素
let images = document.images
获取当前文档中所有的a元素
let links = document.links
根据标签名获取元素列表
<body>
<div></div>
<script>
let elements = document.getElementsByTagName('div')
console.log(elements) // HTMLCollection [div]
</script>
</body>
根据ID获取元素
<body>
<div id="box1"></div>
<script>
let element = document.getElementById('box1')
console.log(element) // <div id="box1"></div>
</script>
</body>
根据类名获取元素列表
<body>
<div class="active">Test</div>
<script>
let elements = document.getElementsByClassName('active')
console.log(elements) // HTMLCollection [div.active]
</script>
</body>
根据name获取元素列表
<body>
<input name="uname"/>
<script>
let elements = document.getElementsByName('uname')
console.log(elements) // NodeList [input]
</script>
</body>
使用CSS选择获取第一个匹配的元素
<body>
<input name="uname"/>
<script>
let element = document.querySelector('[name="uname"]')
console.log(element) // <input name="uname"/>
</script>
</body>
使用CSS选择器获取所有匹配的元素
<body>
<input name="uname"/>
<script>
let elements = document.querySelectorAll('[name="uname"]')
console.log(elements) // NodeList [input]
</script>
</body>
获取所有子元素
获取所有子节点
<body>
<ul id="ul">
<li>li-1</li>
<li>li-2</li>
<li>li-3</li>
<li>li-4</li>
</ul>
<script>
let ul = document.getElementById('ul')
console.log(ul.childNodes) // NodeList(9) [text, li, text, li, text, li, text, li, text]
</script>
</body>
获取所有子标签
console.log(ul.children) // HTMLCollection(4) [li, li, li, li]
获取第一个子元素
获取第一个子节点
<body>
<ul id="ul">
<li>li-1</li>
<li>li-2</li>
<li>li-3</li>
<li>li-4</li>
</ul>
<script>
let ul = document.getElementById('ul')
console.log(ul.firstChild) // #text
</script>
</body>
获取第一个子标签
console.log(ul.firstElementChild) // <li>li-1</li>
获取最后一个子元素
获取最后一个子节点
<body>
<ul id="ul">
<li>li-1</li>
<li>li-2</li>
<li>li-3</li>
<li>li-4</li>
</ul>
<script>
let ul = document.getElementById('ul')
console.log(ul.lastChild) // #text
</script>
</body>
获取最后一个子标签
console.log(ul.lastElementChild) // <li>li-4</li>
获取上一个元素
获取上一个节点
<body>
<ul>
<li>li-1</li>
<li id="li2">li-2</li>
<li>li-3</li>
<li>li-4</li>
</ul>
<script>
let li2 = document.getElementById('li2')
console.log(li2.previousSibling) // #text
</script>
</body>
获取上一个标签
console.log(li2.previousElementSibling) // <li>li-1</li>
获取下一个元素
获取下一个节点
<body>
<ul>
<li id="li1">li-1</li>
<li>li-2</li>
<li>li-3</li>
<li>li-4</li>
</ul>
<script>
let li1 = document.getElementById('li1')
console.log(li1.nextSibling) // #text
</script>
</body>
获取下一个标签
console.log(li1.nextElementSibling) // <li>li-2</li>
获取父级节点
获取父级节点
<body>
<ul>
<li id="li1">li-1</li>
<li>li-2</li>
<li>li-3</li>
<li>li-4</li>
</ul>
<script>
let li1 = document.getElementById('li1')
console.log(li1.parentNode) // <ul>...</ul>
</script>
</body>
获取父级元素
console.log(li1.parentElement) // <ul>...</ul>
获取最近的一个在定位流中的父级元素,如果没有在定位流中的父级元素,则返回body
console.log(li1.offsetParent) // body
节点数据
获取节点名称
<body>
<ul>
<li id="li1">li-1</li>
<li>li-2</li>
<li>li-3</li>
<li>li-4</li>
</ul>
<script>
let li1 = document.getElementById('li1')
console.log(li1.nodeName) // LI
</script>
</body>
console.log(li1.tagName) // LI
获取节点类型
类型 | 说明 |
---|---|
1 | 标签节点 |
2 | 属性节点 |
3 | 文本节点 |
8 | 注释节点 |
<body>
<ul>
<li id="li1">li-1</li>
<li>li-2</li>
<li>li-3</li>
<li>li-4</li>
</ul>
<script>
let li1 = document.getElementById('li1')
console.log(li1.nodeType) // 1
</script>
</body>
获取当前节点的值
只对TEXT
和Comment
节点有效,其余节点均返回null
<body>
<ul>
<li id="li1">li-1</li>
<li>li-2</li>
<li>li-3</li>
<li>li-4</li>
</ul>
<script>
let li1 = document.getElementById('li1')
console.log(li1.firstChild.nodeValue) // li-1
</script>
</body>
获取当前节点以及后代节点的文本内容
<body>
<ul id="ul">
<li>li-1</li>
<li>li-2</li>
<li>li-3</li>
<li>li-4</li>
</ul>
<script>
let ul = document.getElementById('ul')
console.log(ul.textContent)
</script>
</body>
获取或设置当前节点的HTML结构
获取结构
<body>
<ul id="ul">
<li>li-1</li>
<li>li-2</li>
<li>li-3</li>
<li>li-4</li>
</ul>
<script>
let ul = document.getElementById('ul')
console.log(ul.outerHTML)
</script>
</body>
设置结构
ul.outerHTML = "<ul><li>list-item</li></ul>"
获取或设置当前节点内部的HTML结构
获取内部结构
<body>
<ul id="ul">
<li>li-1</li>
<li>li-2</li>
<li>li-3</li>
<li>li-4</li>
</ul>
<script>
let ul = document.getElementById('ul')
console.log(ul.innerHTML)
</script>
</body>
设置内部结构
ul.innerHTML = "<li>list-item</li>"
获取或设置当前元素内部的文本,包含后代元素的文本
获取内部的文本
<body>
<div id='wrapper'>
<div>Hello</div>
</div>
<script>
let wrapper = document.getElementById('wrapper')
console.log(wrapper.innerText) // Hello
</script>
</body>
设置内部的文本
wrapper.innerText = 'Hello HTML'
盒子数据
尺寸 | 说明 | 图示 |
---|---|---|
clientWidth clientHeight | 获取视口的宽和高,不包括边框 | |
offsetWidth offsetHeight | 获取视口的宽和高,包括边框 | |
clientTop clientLeft | 获取上边框和左边框的宽度 |
获取当前元素相对于 offsetParent 的相对位置
<body>
<style>
body{margin:0;}
#wrapper{width: 500px;height: 500px;border:5px solid red;box-sizing: border-box;position: relative;}
#innerbox{width: 200px;height: 200px;border:20px solid blue;margin: 50px;padding: 50px;overflow: auto;}
#content{background-color:aqua;height: 100%;width: 100%;}
</style>
<div id="wrapper">
<div id="innerbox">
<div id="content"></div>
</div>
</div>
<script>
let ib = document.getElementById('innerbox')
console.log(ib.offsetLeft,ib.offsetTop) // 50 50
</script>
</body>
节点操作
克隆节点
不包含后代元素
<body>
<ul id="ul">
<li>li-1</li>
</ul>
<script>
let ul = document.getElementById('ul')
let newUl = ul.cloneNode()
</script>
</body>
包含后代元素
let newUl = ul.cloneNode(true)
添加子节点
作为最后一个子节点添加到当前节点
<body>
<ul id="ul">
<li>li-1</li>
</ul>
<script>
let ul = document.getElementById('ul')
let li = document.createElement('li')
li.innerText = 'list-item'
ul.appendChild(li)
</script>
</body>
作为第一个子节点添加到当前节点
ul.prepend(li)
在当前节点下增加一个子节点,并使该子节点位于参考节点的前面。
<body>
<ul id="ul">
<li id="li">li-1</li>
</ul>
<script>
let ul = document.getElementById('ul')
let li = document.getElementById('li')
let newLi = document.createElement('li')
newLi.innerText = 'list-item'
ul.insertBefore(newLi,li)
</script>
</body>
移除节点
移除当前节点下的指定子节点
<body>
<ul id="ul">
<li id="li1">li-1</li>
<li id="li2">li-2</li>
</ul>
<script>
let ul = document.getElementById('ul')
let li1 = document.getElementById('li1')
ul.removeChild(li1)
</script>
</body>
替换节点
用一个新节点替换掉当前节点下的指定子节点
<body>
<ul id="ul">
<li id="li">li-1</li>
</ul>
<script>
let ul = document.getElementById('ul')
let li = document.getElementById('li')
let newLi = document.createElement('li')
newLi.innerText = 'new list item'
ul.replaceChild(newLi,li)
</script>
</body>
获取或设置节点的隐藏状态
获取节点的隐藏状态
console.log(ul.hidden)
隐藏节点
ul.hidden = true
设置当前节点的焦点
获取焦点
<body>
<input type="text" id='sex' name='sex'>
<script>
let input = document.getElementById('sex')
input.focus()
</script>
</body>
失去焦点
input.blur()
点击当前元素
<body>
<button id="btn" onclick="alert('我被点击了')">按钮</button>
<script>
let btn = document.getElementById('btn')
btn.click()
</script>
</body>
属性
属性查询
获取当前元素的所有属性
<body>
<input type="text" id='sex' name='sex'>
<script>
let input = document.getElementById('sex')
console.log(input.attributes) // NamedNodeMap {0: type, 1: id, 2: name, type: type, id: id, name: name, length: 3}
</script>
</body>
console.log(input.getAttributeNames()) //(3) ["type", "id", "name"]
获取指定属性的值
<body>
<input type="text" id='sex' name='sex'>
<script>
let input = document.getElementById('sex')
console.log(input.getAttribute('type')) // text
</script>
</body>
判断当前元素是否包含指定的属性
<body>
<input type="text" id='sex' name='sex'>
<script>
let input = document.getElementById('sex')
console.log(input.hasAttribute('type')) // true
</script>
</body>
获取元素的自定义属性
<body>
<input type="text" id='sex' name='sex' data-id='1' data-state='del'>
<script>
let input = document.getElementById('sex')
console.log(input.dataset) // DOMStringMap {id: "1", state: "del"}
</script>
</body>
删除属性
移除当前元素的指定属性
<body>
<input type="text" id='sex' name='sex'>
<script>
let input = document.getElementById('sex')
input.removeAttribute('name')
</script>
</body>
添加或修改属性
添加或修改属性
如果设置一个不存在的属性,则为添加
如果设置一个已存在的属性,则为修改
<body>
<input type="text" id='sex' name='sex'>
<script>
let input = document.getElementById('sex')
input.setAttribute('value','男')
</script>
</body>
样式操作
类
获取或设置当前元素的class值
获取class值
<body>
<div id="div" class="wrap active"></div>
<script>
let div = document.getElementById('div')
console.log(div.className) // wrap active
</script>
</body>
设置class值
div.classList = 'strong'
获取当前元素的class列表
<body>
<div id="div" class="wrap active"></div>
<script>
let div = document.getElementById('div')
console.log(div.classList) // DOMTokenList(2) ["wrap", "active", value: "wrap active"]
</script>
</body>
设置样式
字符串形式设置
<body>
<div id="div"></div>
<script>
let div = document.getElementById('div')
div.style = "height:100vh;background-color:red";
</script>
</body>
单独设置
div.style.height = '100vh'
div.style.backgroundColor = 'red'
读取样式
读取行内样式
<body>
<div id="div" style="height: 100vh;background-color: red;"></div>
<script>
let div = document.getElementById('div')
console.log(div.style.backgroundColor) // red
</script>
</body>
读取非行内样式
<body>
<style>
#div{height: 100vh;background-color: red;}
</style>
<div id="div"></div>
<script>
let div = document.getElementById('div')
console.log(window.getComputedStyle(div,null).backgroundColor) // rgb(255, 0, 0)
</script>
</body>
滚动条
获取或设置滚动条左偏移位置
<body>
<style>
body{margin:0;}
#wrapper{width: 500px;height: 500px;border:5px solid red;box-sizing: border-box;}
#innerbox{width: 200px;height: 200px;border:20px solid blue;margin: 50px;padding: 50px;overflow: auto;}
#content{background-color:aqua;height: 200%;width: 200%;}
</style>
<div id="wrapper">
<div id="innerbox">
<div id="content"></div>
</div>
</div>
<script>
let ib = document.getElementById('innerbox')
ib.scrollLeft = 50
</script>
</body>
获取或设置滚动条上偏移位置
ib.scrollTop = 50
设置滚动条左偏移和上偏移
ib.scroll(50,50)
ib.scrollTo(50,50)
DOM事件
事件 = 目标+事件类型+处理操作
事件操作
绑定事件
在DOM上直接绑定事件
事件处理程序直接写在元素上
<button onclick="console.log('按钮被点击了')">按钮</button>
绑定事件处理函数
<body>
<button onclick="clickHandle()">按钮</button>
<script>
function clickHandle(){
console.log('按钮被点击了')
}
</script>
</body>
通过JS绑定事件
直接使用闭包函数作为事件处理函数
<body>
<button id="btn">按钮</button>
<script>
const btn = document.getElementById('btn')
btn.addEventListener('click',function(){
console.log('按钮被点击了')
})
</script>
</body>
绑定事件处理函数
<body>
<button id="btn">按钮</button>
<script>
function clickHandle(){
console.log('按钮被点击了')
}
const btn = document.getElementById('btn')
btn.addEventListener('click',clickHandle)
</script>
</body>
移除事件
<body>
<button id="btn">按钮</button>
<script>
function clickHandle(){
console.log('按钮被点击了')
btn.removeEventListener('click',clickHandle)
}
const btn = document.getElementById('btn')
btn.addEventListener('click',clickHandle)
</script>
</body>
鼠标事件
鼠标单击事件
鼠标的左键
会触发该事件
<body>
<style>
body{margin: 0;padding:50px;box-sizing: border-box;}
#wrapper{height: 300px;width:300px;background-color: #f00;box-sizing: border-box;padding:50px;position: relative;}
#inner{height: 200px;width:200px;background-color: #00f;}
</style>
<div id="wrapper">
<div id="inner"></div>
</div>
<script>
const wrapper = document.getElementById('wrapper')
wrapper.addEventListener('click',function(e){
console.log(e) // MouseEvent {...}
})
</script>
</body>
鼠标双击事件
鼠标的左键
会触发该事件
wrapper.addEventListener('dblclick',function(e){
console.log(e) // MouseEvent {...}
})
鼠标按下事件
鼠标的左键
、中键
和右键
都会触发该事件
wrapper.addEventListener('mousedown',function(e){
console.log(e) // MouseEvent {...}
})
鼠标弹起事件
鼠标的左键
、中键
和右键
都会触发该事件
wrapper.addEventListener('mouseup',function(e){
console.log(e) // MouseEvent {...}
})
鼠标进入事件
进出子元素不触发
wrapper.addEventListener('mouseenter',function(e){
console.log(e) // MouseEvent {...}
})
进出子元素触发
wrapper.addEventListener('mouseover',function(e){
console.log(e) // MouseEvent {...}
})
鼠标移出事件
进出子元素不触发
wrapper.addEventListener('mouseleave',function(e){
console.log(e) // MouseEvent {...}
})
进出子元素触发
wrapper.addEventListener('mouseout',function(e){
console.log(e) // MouseEvent {...}
})
鼠标移动事件
wrapper.addEventListener('mousemove',function(e){
console.log(e) // MouseEvent {...}
})
鼠标右键单击
只有单击鼠标右键时才会触发
wrapper.addEventListener('contextmenu',function(e){
console.log(e) // MouseEvent {...}
})
MouseEvent
属性 | 说明 |
---|---|
e.button | 返回按键索引 0 :左键 1 :中键 2 :右键 |
e.target | 返回触发事件的目标元素 |
e.clientX e.clientY | 返回点击点的坐标,相对于目标元素 |
e.screenX e.screenY | 返回点击点的坐标,相对于屏幕 |
鼠标滚轮滚动事件
只有鼠标滚轮滚动时触发
<body style="height: 100vh;">
<script>
const body = document.body
body.addEventListener('wheel', function (e) {
console.log(e) // WheelEvent {...}
})
</script>
</body>
WheelEvent
属性 | 说明 |
---|---|
e.deltaX e.deltaY | 返回滚轮的滚动量 |
e.target | 返回触发事件的目标元素 |
文本选择事件
该事件只能绑定到<input>
和<textarea>
元素上
<body>
<textarea id='tx' cols="50" rows="50">
That was Wintermute, manipulating the lock the way it had manipulated the drone micro and the dripping chassis of a heroin factory. The Sprawl was a square of faint light. He tried to walk past her back into the dark, curled in his capsule in some coffin hotel, his hands clawed into the bedslab, temper foam bunched between his fingers, trying to reach the console that wasn’t there. Light from a service hatch at the rear wall dulling the roar of the console in faded pinks and yellows. Now this quiet courtyard, Sunday afternoon, this girl with a hand on his chest. Still it was a steady pulse of pain midway down his spine. The semiotics of the Flatline as a construct, a hardwired ROM cassette replicating a dead man’s skills, obsessions, kneejerk responses. Images formed and reformed: a flickering montage of the Sprawl’s towers and ragged Fuller domes, dim figures moving toward him in the dark, curled in his sleep, and wake alone in the tunnel’s ceiling. Why bother with the movement of the train, their high heels like polished hooves against the gray metal of the car’s floor. Strata of cigarette smoke rose from the tiers, drifting until it struck currents set up by the blowers and the chassis of a gutted game console.
</textarea>
<script>
const tx = document.getElementById('tx')
tx.addEventListener('select',function(e){
console.log(e) // Event {...}
})
</script>
</body>
键盘事件
按键被按下事件
<body>
<input type="text" id="input">
<script>
const input = document.getElementById('input')
input.addEventListener('keydown',function(e){
console.log(e) // KeyboardEvent {...}
})
</script>
</body>
按键被弹起事件
input.addEventListener('keyup',function(e){
console.log(e) // KeyboardEvent {...}
})
KeyboardEvent
属性 | 说明 |
---|---|
e.key | 返回按键的值,例如:a ,1 ,Alt |
e.code | 返回物理按键码,例如:KeyA ,Digit1 ,AltLeft |
e.target | 返回触发事件的目标元素 |
视图事件
滚动事件
<body>
<style>
body{margin: 0;padding:50px;box-sizing: border-box;}
#wrapper{height: 300px;width:300px;background-color: #f00;box-sizing: border-box;padding:50px;position: relative;overflow: auto;}
#inner{height: 500px;width:500px;background-color: #00f;}
</style>
<div id="wrapper">
<div id="inner"></div>
</div>
<script>
const wrapper = document.getElementById('wrapper')
wrapper.addEventListener('scroll',function(e){
console.log(e) // Event {...}
})
</script>
</body>
窗口尺寸重置事件
作用于window
对象
<body>
<script>
window.addEventListener('resize',function(e){
console.log(e) // Event {...}
})
</script>
</body>
拖拽事件
搭建基本的HTML页面
<body>
<style>
body{margin: 0;padding:50px;box-sizing: border-box;}
#wrapper{display: flex;justify-content: space-between;gap:10px;}
#wrapper ul{flex:1;border:1px solid red;list-style: none;padding: 0;height: 300px;}
#wrapper ul li{padding: 10px;border:1px solid blue;margin: 5px;text-align: center;}
</style>
<div id="wrapper">
<ul class="target">
<li>li-1</li>
<li>li-2</li>
<li>li-3</li>
<li>li-4</li>
<li>li-5</li>
</ul>
<ul class="target"></ul>
<ul class="target"></ul>
</div>
</body>
设置可拖动的元素
<script>
// 使 li 可以被拖动
const lis = document.getElementsByTagName('li')
for(li of lis){
li.setAttribute('draggable',true)
}
</script>
设置拖动的目标区域
<script>
// 使 li 可以被拖动
/* ... */
// 设置 .target 为拖动的目标区域
const targets = document.getElementsByClassName('target')
for(target of targets){
target.addEventListener('dragover',function(e){
e.preventDefault()
})
}
</script>
给可拖动元素绑定开始拖动事件
// 使 li 可以被拖动
const lis = document.getElementsByTagName('li')
for(li of lis){
li.setAttribute('draggable',true)
// 开始拖动
li.addEventListener('dragstart',function(e){
current = this
})
}
给目标元素绑定释放事件
// 设置 .target 为拖动的目标区域
const targets = document.getElementsByClassName('target')
for(target of targets){
/* ... */
// 释放元素
target.addEventListener('drop',function(e){
this.appendChild(current)
})
}
设置进入目标区域后,目标区域的背景颜色
// 设置 .target 为拖动的目标区域
const targets = document.getElementsByClassName('target')
for(target of targets){
/* ... */
// 释放元素
/* ... */
// 进入目标区域
target.addEventListener('dragenter',function(e){
this.style.backgroundColor = 'rgba(255,0,0,0.3)'
})
}
设置离开目标区域后,目标区域的背景颜色
// 设置 .target 为拖动的目标区域
const targets = document.getElementsByClassName('target')
for(target of targets){
/* ... */
// 释放元素
/* ... */
// 进入目标区域
/* ... */
// 离开目标区域
target.addEventListener('dragleave',function(e){
this.style.backgroundColor = '#fff'
})
}
设置拖动结束后,目标区域的背景颜色
// 使 li 可以被拖动
const lis = document.getElementsByTagName('li')
for(li of lis){
li.setAttribute('draggable',true)
// 开始拖动
/* ... */
// 结束拖动
li.addEventListener('dragend',function(e){
this.parentNode.style.backgroundColor = '#fff'
})
}
元素拖动时,在父级消失
// 使 li 可以被拖动
const lis = document.getElementsByTagName('li')
for(li of lis){
li.setAttribute('draggable',true)
// 开始拖动
/* ... */
// 结束拖动
/* ... */
// 正在拖动
li.addEventListener('drag',function(e){
this.parentNode.removeChild(this)
})
}
资源事件
资源加载事件
window
触发
<body>
<script>
window.addEventListener('load', function(e) {
console.log(e);
});
</script>
</body>
文档加载完成后触发
<body onload="loadHandle(event)">
<h1>Hello HTML</h1>
<script>
function loadHandle(e){
console.log(e)
}
</script>
</body>
图片加载触发
<body>
<img src="https://www.yaconit.com/public/images/logo.png" onload="loadHandle(event)">
<script>
function loadHandle(e){
console.log(e)
}
</script>
</body>
表单事件
表单提交事件
<body>
<form id="login">
<div>
<label for="uname">账号:</label>
<input type="text" id="uname" name="uname">
</div>
<div>
<label for="upass">密码:</label>
<input type="password" id="upass" name="upass">
</div>
<div>
<input type="submit" value="登陆"/>
</div>
</form>
<script>
const loginForm = document.getElementById('login')
loginForm.addEventListener('submit',function(e){
console.log(e) // SubmitEvent {...}
e.preventDefault() // 禁止表单提交
})
</script>
</body>
更改事件
<input type="text">
和<textarea>
在失去焦点时,才会判断是否产生了更改
<select>
、<input type="radio">
和<input type="checkbox">
在每次更改选项时就会触发该事件
<body>
<form id="login">
<input type="text" id="uname" name="uname">
</form>
<script>
const uname = document.getElementById('uname')
uname.addEventListener('change',function(e){
console.log(e) // Event {...}
})
</script>
</body>
输入事件
<input>
和<textarea>
在输入时触发该事件
<body>
<form id="login">
<input type="text" id="uname" name="uname">
</form>
<script>
const uname = document.getElementById('uname')
uname.addEventListener('input',function(e){
console.log(e) // InputEvent {...}
})
</script>
</body>
焦点事件
获取焦点事件
<body>
<input type="text" id="input">
<script>
const input = document.getElementById('input')
input.addEventListener('focus', function (e) {
console.log(e) // FocusEvent {...}
})
</script>
</body>
失去焦点事件
input.addEventListener('blur', function (e) {
console.log(e) // FocusEvent {...}
})
媒体事件
媒体加载事件
媒体的第一帧已经加载完成
<body>
<video id="vm" src="https://www.w3school.com.cn/i/movie.ogg" controls>
您的浏览器不支持 video 标签。
</video>
<script>
const vm = document.getElementById('vm')
vm.addEventListener('loadeddata',function(e){
console.log(e) // Event {...}
})
</script>
</body>
媒体已经加载完成
vm.addEventListener('suspend',function(e){
console.log(e) // Event {...}
})
媒体播放事件
媒体开始播放
vm.addEventListener('play',function(e){
console.log(e) // Event {...}
})
媒体暂停播放,用户主动暂停
vm.addEventListener('pause',function(e){
console.log(e) // Event {...}
})
媒体暂停播放,由于网络原因,因缺少数据而被迫暂停
vm.addEventListener('waiting',function(e){
console.log(e) // Event {...}
})
媒体播放结束
vm.addEventListener('ended',function(e){
console.log(e) // Event {...}
})
按压事件
开始按压
<body style="height: 100vh;">
<script>
document.addEventListener('touchstart',function(e){
console.log(e) // TouchEvent {...}
})
</script>
</body>
结束按压
document.addEventListener('touchend',function(e){
console.log(e) // TouchEvent {...}
})
按压时移动
document.addEventListener('touchmove',function(e){
console.log(e) // TouchEvent {...}
})
Window
窗口操作
新开窗口
<body>
<button onclick="window.open()">关闭当前窗口</button>
</body>
关闭当前窗口
<body>
<button onclick="window.close()">关闭当前窗口</button>
</body>
弹窗
警告框
window.alert('Hello')
简写
alert("Hello")
选择框
点击确定
,返回true
点击取消
,返回false
let choose = window.confirm('请选择')
console.log(choose)
提示输入框
点击确定
,返回用户输入的内容
点击取消
,返回null
let choose = window.prompt('请输入')
console.log(choose)
打印当前文档
window.print()
Location
页面地址
获取完整路径
console.log(location.href) // http://127.0.0.1:5500/demo/index.html?uname=zs&upass=123#login
获取域名和端口
console.log(location.host) // 127.0.0.1:5500
获取域名
console.log(location.hostname) // 127.0.0.1
获取端口
console.log(location.port) // 5500
获取协议
console.log(location.protocol) // http:
获取路径
console.log(location.pathname) // /demo/index.html
获取查询字符串
console.log(location.search) // ?uname=zs&upass=123
获取锚路径
console.log(location.hash) // #login
重新加载
location.reload()
跳转页面
会产生历史记录
localtion.href = 'https://www.yaconit.com/'
localtion = 'https://www.yaconit.com/'
location.assign('https://www.yaconit.com/')
不会产生历史记录
localtion.replace('https://www.yaconit.com/')
表单数据
创建表单数据对象
<body>
<form id="login">
<div>
<label for="uname">账号:</label>
<input type="text" id="uname" name="uname" value="张三">
</div>
<div>
<label for="upass">密码:</label>
<input type="password" id="upass" name="upass" value="123">
</div>
<div>
<input type="submit" value="登陆" />
</div>
</form>
<script>
const loginForm = document.getElementById('login')
let fd = new FormData(loginForm)
</script>
</body>
表单数据对象操作
查询数据
查询指定name的数据,返回单一值
console.log(fd.get('uname')) // 张三
查询指定name的数据,返回数组
console.log(fd.getAll('uname')) // ["张三"]
检查是否有指定的name
console.log(fd.has('uname')) // true
获取所有键值对
for(entry of fd.entries()){
console.log(entry[0],entry[1])
}
追加数据
fd.append('sex','男')
删除数据
fd.delete('uname')
获取所有的键
for(key of fd.keys()){
console.log(key)
}
获取所有的值
for(value of fd.values()){
console.log(value)
}
修改或新增数据
fd.set('uname','李四')
上传文件解析
获取上传文件对象
<body>
<label for="file">头像:</label>
<input type="file" name="file" id="file" onchange="changeHandle()"/>
<script>
function changeHandle(){
let fileInput = document.getElementById('file')
let files = fileInput.files
console.log(files)
}
</script>
</body>
查看文件名称
for(file of files){
console.log(file.name)
}
查看文件类型
for(file of files){
console.log(file.type)
}
查看文件大小
单位:字节
for(file of files){
console.log(file.size)
}
查了文件路径
for(file of files){
console.log(window.URL.createObjectURL(file))
}
媒体操作
播放媒体
<body>
<video id="vd" src="https://www.w3school.com.cn/i/movie.ogg">
您的浏览器不支持 video 标签。
</video>
<script>
let vd = document.getElementById('vd')
vd.play()
</script>
</body>
暂停播放媒体
vd.pause()
显示媒体控制器
true
显示控制器false
不显示控制器
vd.controls = true
媒体自动播放
true
自动播放false
不自动播放
vd.autoplay = true
设置媒体当前播放时间
单位为秒
vd.currentTime = 2
循环播放
true
循环 false
不循环
vd.loop = true
静音模式
true
静音 false
不静音
vd.muted = true
音量调节
1
音量最大,0
音量最小
vd.volume = 0.3
历史记录
后退
history.back()
前进
history.forward()
跳转
正整数
表示前进几个记录 负整数
表示后退几个记录
history.go(-1)
本地数据存储
本地永久存储
关闭浏览器,数据不会丢失
存储或修改数据
localStorage.setItem('name','张三')
获取数据
console.log(localStorage.getItem('name'))
删除数据
localStorage.removeItem('name')
清空数据
localStorage.clear()
获取本地存储条目数
console.log(localStorage.length) // 1
本地临时存储
关闭浏览器,数据就会被清空
存储或修改数据
sessionStorage.setItem('name','张三')
获取数据
console.log(sessionStorage.getItem('name'))
删除数据
sessionStorage.removeItem('name')
清空数据
sessionStorage.clear()
获取本地存储条目数
console.log(sessionStorage.length) // 1