标准

ES6

调试

Console查看执行结果和报错,点击报错位置可以直接跳转

Sources查看具体报错代码

引入

任意位置(bodyhead):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 直接写在标签 -->
<script type="module">
let x = 3;
console.log(x); // 输出位置:F12->console
</script>

<!-- 引入外部js文件 -->
<script type="module" src="./static/js/index.js"></script>

<!-- 引入部分外部js文件(推荐) -->
<script type="module">
import { print } from "./static/js/index.js";
import { print_x } from "./static/js/index2.js";
print();
print_x();
</script>

type="module"用于限制变量作用域为当前标签内部

执行顺序

  • 从上到下
  • 事件驱动

关系

  • CSS控制HTML
  • JS控制CSSHTML

变量

声明

  • 变量:let
  • 常量:const

let是最新标准,作用域比var更严格

类型

动态类型,不需要声明

查看变量类型:console.log(typeof a)

常见

  • number
  • string:不区分单引号和双引号;不可以更改字符(使用substr重新构造)
  • booleantruefalse
  • object
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let dic = {
name: "wy",
age: 18
}
let key = "name";

// 输出键值
console.log(dic["name"]);
console.log(dic.age);
console.log(dic[key]);

// 输出字典
console.log(dic);

// 新建键
dic["school"] = "cqupt";
console.log(dic["school"]);

// 删除键
delete dic.school;
  • undefined
1
2
let t;
console.log(typeof t);

运算符

  • 乘方:**
  • 整除:parseInt(5 / 3)
  • 相等和不相等:===!==

输入输出

选择器

1
2
3
4
5
6
// 获取第一个满足的标签
let input = document.querySelector("textarea");
// 获取所有满足的标签
let input_all = document.querySelectorAll("textarea");
// 类选择器
let input_class = document.querySelector(".class");

前端输入输出

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 http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./static/css/style.css">
</head>

<body>
<span>输入:</span>
<br>
<textarea name="" id="" cols="30" rows="10"></textarea>
<br>
<button>Run</button>
<br>
<pre></pre>

<script type="module">
import { main } from "./static/js/index.js";

main();
</script>
</body>

</html>

JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let input = document.querySelector("textarea");
let run = document.querySelector("button");
let output = document.querySelector("pre");

function main() {
run.addEventListener("click", function () {
let s = input.value;
output.innerHTML = s;
});
}

export {
main
}

终端输入输出

1
2
3
4
5
6
7
8
9
10
11
12
let buf = "";

process.stdin.on("readable", function() {
let chunk = process.stdin.read();
if (chunk) buf += chunk.toString();
});


process.stdin.on("end", function() {
let q = buf.split(' ');
console.log(q[0] + q[1]);
});

格式化字符串

1
2
3
let name = "wy";
let age = 9;
let s = `My name is ${name}. I'm ${age * 2} yeas old.`;

判断语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
run.addEventListener("click", function () {
let s = parseInt(input.value);
let res;

if (s >= 90) {
res = 'A';
} else if (s >= 80) {
res = 'B';
} else if (s >= 70) {
res = 'C';
} else if (s >= 60) {
res = 'D';
} else {
res = 'E'
};

output.innerHTML = res;
})

循环语句

遍历下标

1
2
3
for (let value in d) {
console.log(d[value]);
};

遍历键值

注意

  • 修改键值本身不起作用
  • 如果键值是地址,则可以索引并修改其内容
1
2
3
4
5
6
7
let d = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];

for (let value of d) {
value[0] = 10;
};

console.log(d);

对象

键用不用引号包裹都视为字符串

空对象:let a = null;

没有任何元素的对象:let a = {};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let person = {
name: 'wy',
age: 18,
money: 999,
friends: ['dqy', 'ljy', 'wz'],
clothes: {
color: 'black',
price: 999
},
add_money: function (x) {
this.money += x;
}
};

function main() {
console.log(`账户余额:${person.money}`);
person.add_money(1);
console.log(`账户余额:${person.money}`);
};

export {
main
}

数组

元素可以是不同类型(包括函数)

长度:a.length

末尾添加:a.push(5)

末尾删除:a.pop(5)

删除连续元素:a.splice(2, 3) //删除从下标2开始的3个元素

排序:a.sort()

1
2
3
4
5
6
let a = [5, 3, 1, 2, 4];

a.sort(function(a, b) {
// 返回值:正->a在b后面;负->a在b前面
return a - b;
});

下标可以不连续

1
2
let a = [1];
a[5] = 5;

函数

没有返回值默认返回undefined

1
2
3
4
5
6
7
function add(a, b) {};

let add = function(a, b) {};

let add = (a, b) => {};

let add = a => {};

定义类

类中的属性和方法直接赋值,不需要letfunction

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}

init() {
this.sum = this.x + this.y;
}

toString() {
return `(${this.x}, ${this.y})`;
}
}

静态属性和方法与类绑定,用类名访问

静态成员可以被继承

静态成员相当于全局变量或函数,一处修改全局改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Test {
constructor() {
++Test.cnt;
}
static print(str) {
console.log(str);
};
}
Test.print("Hello World!");

Test.cnt = 0; // 定义静态变量

class Test1 extends Test {}

Test1.print("Hello World!");

生成实例

1
let p = new Point(3, 4);

继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}

toString() {
return `(${this.x}, ${this.y})`;
}
}

class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y); // 首先初始化父类
this.color = color;
}

toString() {
return `${this.color} ${super.toString()}`; // super代表当前父类的实例
}
}

事件

常见的触发函数

鼠标

addEventListener函数为元素绑定事件的触发函数

event:默认参数,可以任意命名

  • event.type: 事件类型(点击、滚动)
  • event.button: 0左键; 1滚轮; 2右键
  • event.clientX: 触发位置的横坐标
  • event.clientY: 触发位置的纵坐标
1
2
3
4
5
6
7
8
9
10
11
let div = document.querySelector('div');

function main() {
div.addEventListener('mouseup', function (event) {
console.log(event.type, event.button);
})

div.addEventListener('mousedown', function (event) {
console.log(event.type, event.button);
})
}

键盘

event:

  • event.code: 按下的键
  • event.shiftKey: 是否按下shift
  • event.ctrlKey: 是否按下ctrl
  • event.altKey: 是否按下alt
1
2
3
4
5
6
7
8
9
10
let input = document.querySelector('input');

input.addEventListener('keydown', function (event) {
console.log(event.type, event.code, event.shiftKry, event.ctrlKey);
})

// ketpress只识别能显示出来的字符按键
input.addEventListener('keypress', function (event) {
console.log(event.type, event.code);
})

表单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 聚焦
input.addEventListener('focus', function (event) {
console.log(event.type);
})

// 取消聚焦
input.addEventListener('blur', function (event) {
console.log(event.type);
})

// 内容修改,取消聚焦时才会检查内容是否改变
input.addEventListener('change', function (event) {
console.log(event.type);
})

窗口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 窗口大小改变
window.addEventListener('resize', function (event) {
console.log(event.type);
})

// 窗口滚动,不是鼠标滚轮
window.addEventListener('scroll', function (event) {
console.log(event.type);
})

// 页面加载完毕
window.addEventListener('load', function (event) {
console.log(event.type);
})

常用库

jQuery

引入jQ

1
<script src="https://cdn.acwing.com/static/jquery/js/jquery-3.3.1.min.js"></script>

jQuary选择器

  • 选出所有符合条件的标签
  • 和CSS选择器完全一样

标签

1
let div = $('div');

1
let mydiv = $('.mydiv');
1
let mydiv = $('.mydiv > p');

ID

1
let idiv = $('#idiv');

事件绑定与解绑

绑定

1
2
3
4
let div = $('div');
div.on('click', function () {
console.log('click div');
});
1
2
3
4
let div = $('div');
div.click(function () {
console.log('click div');
});

触发函数命名

1
2
3
4
5
6
7
8
let div = $('div');
div.on('click.name1', function () {
console.log('click1');
div.off('click.name2');
});
div.on('click.name2', function () {
console.log('click2');
});

解绑

1
div.off('click');

事件传递机制

向上传递

adiv内部,点击a同时触发adivclick函数

1
2
3
<div>
<a href="#">Test</a>
</div>

关闭向上传递:

1
2
3
4
5
6
7
8
let div = $('div');
let $a = $('div a');
div.on('click', function () {
console.log('click');
});
$a.on('click', function (e) {
e.stopPropagation();
});

阻止当前事件,放行向上传递:

1
2
3
$a.on('click', function (e) {
e.preventDefault();
});

阻止当前事件并且关闭向上传递:

1
2
3
4
$a.on('click', function (e) {
e.preventDefault();
e.stopPropagation();
});
1
2
3
$a.on('click', function (e) {
return false;
});

元素隐藏与展示

向左上角缩放

1
2
3
4
5
6
7
8
9
10
11
let div = $('div');
let btn_hide = $('#hide-btn');
let btn_show = $('#show-btn');

btn_hide.click(function () {
div.hide(1500); // 1500ms
});

btn_show.click(function () {
div.show(1500);
});

此类特效很多

元素添加与删除

添加的元素可以添加CSS样式

尾插

1
2
3
4
5
6
7
div.click(function () {
let $a = $(
`<a class="myBlog" href="https://www.dqywy.top" target="blank">
<span>小窝</span>
</a>`);
div.append($a); // 添加元素
})
1
2
3
4
5
6
div.click(function () {
div.append($(
`<a class="myBlog" href="https://www.dqywy.top" target="blank">
<span>小窝</span>
</a>`));
})

头插

div.pretend()

删除当前元素

1
2
3
4
5
6
7
8
9
10
11
12
let $a = $(
`<a href="https://www.dqywy.top" target="blank">
<span>小窝</span>
</a>`);

div.click(function () {
div.append($a);
})

div.dblclick(function () {
$a.remove();
})

删除当前元素的所有子树

div.empty()

通过类间接操作CSS

添加类

1
2
3
div.click(function () {
div.addClass('my-div');
})

删除类

1
2
3
div.click(function () {
div.removeClass('my-div');
})

判断类是否存在

1
div.hasClass('my-div');

直接操作CSS

查看属性

1
div.css('background-color');

修改css属性

1
div.css('background-color', 'orange');
1
2
3
4
5
div.css({
width: '200px',
height: '200px',
'background-color': 'orange' // 带特殊符号要加引号
});

标签属性

获取

1
div.attr('id');

设置

1
div.attr('id', 'my-div');

标签内容

获取文本

1
console.log(div.text());

修改文本

1
div.text('好稀饭w悦呀~');

获取html内容

1
div.html();

获取输入框的内容

1
2
3
4
div.click(function () {
let input = $('input');
console.log(input.val());
})

修改输入框的内容

1
2
3
4
div.click(function () {
let input = $('input');
input.val('w悦');
})

查找标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 查找父元素
console.log(div2.parent());

// 父元素且为div
console.log(div2.parent('div'));

// 查找所有祖先元素
console.log(div3.parents());

// 查找所有是div的祖先元素
console.log(div3.parents('div'));

// 查找子元素
console.log(div1.children());

// 查找是div的子元素
console.log(div1.children('div'));

// 查找所有是div的后代元素,find必须加条件
console.log(div1.find('div'));

ajax

GET方法

不刷新页面从服务器端获取某些数据(json)

1
2
3
4
5
6
7
8
9
10
$.ajax({
url: url, // 后端链接
type: "GET",
data: {
},
dataType: "json",
success: function (resp) { // 操作成功成功调用回调函数,resp存储后端返回的信息

},
});

POST方法

提交表单

1
2
3
4
5
6
7
8
9
10
$.ajax({
url: url,
type: "POST",
data: {
},
dataType: "json",
success: function (resp) {

},
});

辅助函数

延时函数

setTimeout(func, time)

  • time毫秒之后执行
  • 执行周期=函数调用时间+time,不均匀

clearTimeout(func_id)

周期执行

setInterval(func, time):time代表将当前函数压入栈中的时间间隔,栈中存在其他函数,执行时间无法确定

clearInterval(func_id)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let $div = $('div');
let func_id;

$div.click(function () {
if (func_id) return;

func_id = setInterval(function () {
console.log('wy');
}, 1000);
})

$div.dblclick(function () {
clearInterval(func_id);
})

浏览器刷新页面之前执行

requestAnimationFrame(func)

  • 时间间隔均匀
  • 切换到后台不再执行
1
2
3
4
5
6
function step() {
$('div').width($('div').width() + 1);
requestAnimationFrame(step);
}

requestAnimationFrame(step);

设置时间限制

1
2
3
4
5
6
7
8
9
function step(timestamp) {
$('div').width($('div').width() + 1);
// timestamp代表执行时刻(ms)
if (timestamp / 1000 <= 3) {
requestAnimationFrame(step);
}
}

requestAnimationFrame(step);

设置结束条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let func_id;

function step(timestamp) {
$('div').width($('div').width() + 1);
func_id = requestAnimationFrame(step);
};
func_id = requestAnimationFrame(step);

$('div').click(function () {
cancelAnimationFrame(func_id);
});

$('div').dblclick(function () {
func_id = requestAnimationFrame(step);
});

Map与Set

Map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let map = new Map();
map.set('name', 'w悦');
map.set('age', 18);
map.set('test', 0);
console.log(map.get('name')); // 获取值
console.log(map.has('age')); // 是否存在
console.log(map.size); // 键值对个数

// 遍历1
for (let [key, value] of map) {
console.log(`${key}: ${value}`);
}

// 遍历2
map.forEach(function (value, key) {
console.log(`${key}: ${value}`);
});

map.delete('test'); // 删除
map.clear(); // 清空

Set

1
2
3
4
5
6
7
8
9
10
let set = new Set();
set.add('wy');
set.add(18);
set.add(function () {
console.log('w悦');
});
console.log(set.has(18));
set.delete(18);
console.log(set.size);
set.clear();

localStorage

在用户浏览器存储键值对(关闭浏览器、关机、清除缓存仍然存在)

用户查看:Application -> Storage -> Local storage

  • setItem(key, value):插入
  • getItem(key):查找
  • removeItem(key):删除
  • clear():清空
1
2
3
4
localStorage.setItem('name', 'w悦');
console.log(localStorage.getItem('name'));
localStorage.removeItem('name');
localStorage.clear();

数据存储

服务端:

  • 云盘
  • mysql
  • redis

客户端:

  • 内存(js变量)
  • localStorage

JSON

字符串/字节对象双向转换

  • JSON.parse():将字符串解析成对象
  • JSON.stringify():将对象转化为字符串
1
2
3
4
5
6
let obj = {
name: 'wy',
age: 18
};
let str = JSON.stringify(obj);
let new_obj = JSON.parse(str);

日期

当前时刻(从1970.1.1 00:00:00经过的ms

1
console.log(Date.now());

任意时刻:北京时间2022年4月15日 15:30:00

1
console.log(Date.parse("2022-04-15T15:30:00.000+08:00"));

API

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
let start_time = new Date();    // 无参表示当前时间

// 计算两个日期的差值
console.log(start_time - new Date("2022-04-15T15:30:00.000+08:00"));

// 星期
console.log(start_time.getDay());

// 日
console.log(start_time.getDate());

// 月(0~11)
console.log(start_time.getMonth() + 1);

// 年
console.log(start_time.getFullYear());

// 小时
console.log(start_time.getHours());

// 分钟
console.log(start_time.getMinutes());

// 秒
console.log(start_time.getSeconds());

WebSocket

与服务器建立全双工通信(两端都可以主动发起通信)

ajax是用http,只能前端主动发起请求

  • new WebSocket(‘ws://localhost:8080’);:建立ws连接。
  • send():向服务器端发送一个字符串。一般用JSON将传入的对象序列化为字符串。
  • onopen:类似于onclick,当连接建立时触发。
  • onmessage:当从服务器端接收到消息时触发。
  • close():关闭连接。
  • onclose:当连接关闭后触发。

window

  • window.open("https://www.acwing.com"):在新标签栏中打开页面。
  • location.reload():刷新页面。
  • location.href = "https://www.acwing.com":在当前标签栏中打开页面。
1
2
3
4
5
6
7
8
9
10
11
$div.click(function () {
window.open("https://www.dqywy.top");
});

$div.click(function () {
location.reload();
});

$div.click(function () {
location.href = "https://www.dqywy.top";
});

canvas