html+css+js基础

html+css+js基础

html

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!--使用 <meta> 元素来描述HTML文档的描述,关键词,作者,字符集等-->
<title>菜鸟教程(unboob.com)</title>
</head>
<body>
<h1>标题</h1>
<h2>标题</h2>
<p>段落</p>
<a href="#section2">跳转到第二部分</a>
<br>
<a href="https://www.runoob.com/html/html-basic.html">链接</a>
<br>
<hr>
<p>hr标签在HTML页面中创建水平线</p>
<hr>
<!-- 注释 -->
<p>浏览器会自动地在段落的前后添加空行</p>\u2000-\u206F
<p>这个是<br>分行</p>
<hr>
<b>加粗</b><br><br>
<strong>加粗</strong><br><br>
<big>放大</big>
<small>缩小</small>
<i>斜体</i><br><br>
<em>斜体</em><br><br>
<sub>下标</sub><sup>上标</sup>
<hr>
<img src="https://www.runoob.com/images/logo.png" width="258" height="39" />
<hr>
<pre>此例演示如何使用pre标签
对空行和 空格
进行控制
</pre>
<hr>
<p><del>删除</del><ins>插入</ins></p>
<hr>
<!-- 在页面中的某个位置 -->
<p>这个地方是跳转的第二部分<a name="section2"></a></p>
<hr>
<a href="https://www.runoob.com/" target="_blank">访问菜鸟教程!</a>
<!--_self 在本页面打开-->
<p>如果你将 target 属性设置为 &quot;blank&quot;, 链接将在新窗口打开。</p>
<hr>
<a id="tips">有用的提示部分</a>
<a href="#tips">访问有用的提示部分</a>
<hr>
<p>无边框的图片链接:
<a href="http://www.runoob.com/html/html-tutorial.html">
<img border="0" src="smiley.gif" alt="HTML 教程" width="32" height="32"></a></p>
</body>
</html>

2

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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style type="test/css">
body{
background-color: rgb(194, 194, 128);
}
p{
color: blueviolet;
}
</style>
<link rel="shortcut icon" href="https://csdiy.wiki/images/title.png">
<!--带图片的标签-->
<title>菜鸟教程(runoob.com)</title>
<base href="https://www.runoob.com/images/" target ="_blank">
</head>
<body>
<img src ="logo.png" border="0" alt="alt" width="500" height="100">
<br><br>
<a href="https://www.runoob.com/images/">菜鸟教程</a>
<h1>标题</h1>
<p>段落</p>
<br>
<a href="http://www.runoob.com/" style="text-decoration:none;">访问 runoob.com!</a>
<!--没有下划线的链接-->
<hr>
<p>内联样式</p>
<p style="color:rgba(10, 254, 14, 0.221);margin-left:20px;">段落</p>
<hr>
<body style="background-color: rgb(195, 161, 178);">
<h2 style="background-color: blueviolet;">标题</h2>
<p style="background-color: aquamarine;">段落</p>
</body>
<hr>
<h1 style="text-align: center;">居中对齐</h1>
<hr>
</body>
</html>

3

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试</title>
</head>
<body>
<table>
<thead>
<tr>
<th>列标题1</th>
<th>列标题2</th>
<th>列标题3</th>
</tr>
</thead>
<tbody>
<tr>
<td>行1,列1</td>
<td>行1,列2</td>
<td>行1,列3</td>
</tr>
<tr>
<td>行2,列1</td>
<td>行2,列2</td>
<td>行2,列3</td>
</tr>
</tbody>
</table>
<hr>
<p>
每个表格从一个 table 标签开始。
每个表格行从 tr 标签开始。
每个表格的数据从 td 标签开始。
</p>
<h4>一列:</h4>
<table border="1">
<tr>
<td>100</td>
</tr>
</table>
<h4>一行三列:</h4>
<table border="1">
<tr>
<td>100</td>
<td>200</td>
<td>300</td>
</tr>
</table>
<h4>两行三列:</h4>
<table border="1">
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
</tr>
<tr>
<td>100</td>
<td>200</td>
<td>300</td>
</tr>
<tr>
<td>400</td>
<td>500</td>
<td>600</td>
</tr>
</table>
</body>
<hr>
<h4>单元格跨两列:</h4>
<table border="1">
<tr>
<th>Name</th>
<th colspan="2">Telephone</th>
</tr>
<tr>
<td>Bill Gates</td>
<td>555 77 854</td>
<td>555 77 855</td>
</tr>
</table>
<table>
</table>
</html>

4

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试网页</title>
</head>
<body>
<h1>h1</h1>
<h2>h2</h2>
</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
<form>
生日: <input type="text"><br>
年龄: <input type="text" >
</form>
<form>
密码: <input type="password">
</form>
<form>
<input type="radio" >China<br>
<input type="radio" >UK
</form>
<form>
<input type="checkbox">China<br>
<input type="checkbox">UK
</form>
<form >
心情: <input type="text">
<input type="submit" >
</form>
<ol>
<li>你好</li>
<li>hello</li>
</ol>
<ul>
<li>你好</li>
<li>hello</li>
</ul>

5

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
<font color="" size="" face=""></font> <!-- 字体 -->
<h1></h1> <!--标题 -->
<p></p> <!-- 段落 -->
<b></b> <!--粗体-->
<i></i> <!--斜体-->
<hr><!--下划线-->
<br><!--换行-->
<img src="" width="" height="" alt="" title=""/>
<!--type属性: circle: 空心圆; square: 实心正方形-->
<!--无序列表标签-->
<ul type="square">
<li>a</li>
<li>b</li>
</ul>
<!--有序列表标签-->
<!--
start:起始索引(默认是1)
type属性:1:阿拉伯数字; a:小写英文字母; A:大写英文字母; i:小写罗马数字; I:大写罗马数字
-->
<ol start="1" type="1">
<li>乔丹</li>
<li>詹姆斯</li>
</ol>

<!--超链接标签-->
<!--target属性: 链接打开方式-->
<a href="指定需要跳转的目标路径" target="打开的方式">需要展现给用户查看的内容</a>
<!--假链接-->
<a href="#">假链接</a>
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
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<table border="1px" width="600px" cellspacing="0px" cellpadding="10px" bgcolor="navajowhite" align="center">
<!--边框、宽度、单元格间距、单元格内边距、背景颜色和对齐方式-->
<caption>表格标题</caption>
<tr>
<th>姓名</th>
<th>性别</th>
<th>地址</th>
</tr>

<tr align="center">
<td rowspan="2">11</td>
<td>12</td>
<td>13</td>
</tr>

<tr align="center">
<td>22</td>
<td>23</td>
</tr>

<tr align="center">
<td>31</td>
<td colspan="2">32</td>
</tr>
</table>
</body>
</html>

table 中定义 tr, tr 中定义 td, td 中存放内容

6

表单标签
<form></form>
输入类型 <input> 选择菜单 <select> 文本域 <textarea>

input

<input type="xxx"/>

  • text(默认) 文本框
  • password 密码框
  • radio 单选框:同一组单选框 name 属性相同
  • checkbox 复选框:同一组多选框 name 属性相同
  • file 文件选择框
  • date 日期选择框
  • hidden 隐藏域:向服务器提交数据,不在页面上展示出来
  • submit 提交按钮:内置提交表单的功能
  • button 普通按钮:不内置任何功能,需要在学习 js 之后给它绑定点击事件
  • reset 重置按钮:内置重置表单的功能

select

1
2
3
4
5
6
7
8
<select name="">
<!--如果option没有添加value属性,那么提交数据时就会提交选中的option标签体的内容-->
<!--如果option添加了value属性,那么提交数据时就会提交选中的option标签体的value值-->
<!--option标签通过selected属性设置默认选中-->
<option value="">显示的内容1</option>
<option value="">显示的内容2</option>
</select>

textarea

1
<textarea row="20" cols="30" name="introduce"></textarea>

如果表单项的数据需要提交给服务器,必须具备 name 属性
同一组单选、多选框需要具备相同的 name
输入框、密码框、文件选择框、日期选择框等等的 value 属性的值,就是你输入的值
单选或多选框,默认 value 均为 on,所以我们需要手动给单选框和多选框设置 value

readonly 属性:表示只读,数据可以向服务器提交
disabled 属性:表示不可用, 数据无法向服务器提交
placeholder 属性:表示输入提示
checked 属性:单选和多选框也可以设置默认选中

7

1
2
3
4
5
6
7
8
9
<a id="top"></a>
<a href="#top">回到顶部</a>

<a><img src="./img/dog.jpg"/><br/></a>

<details>
<summary>概要信息</summary>
详情信息
</details>

css

层叠样式表

1. CSS 语法

CSS 规则由选择器和声明块组成。

  • 选择器:用于选择页面上的 HTML 元素。
  • 声明块:包含多个 CSS 声明,每个声明定义元素的某个样式属性。
1
2
3
选择器 {
属性名: 属性值;
}

示例

1
2
3
4
p {
color: red;
font-size: 16px;
}
  • 选择器:p(选择所有 <p> 元素)
  • 声明块:color: red;font-size: 16px;(将段落的文字颜色设为红色,字体大小设为 16 像素)

2. 将 CSS 添加到 HTML 中

1. 内联样式(Inline CSS)

直接在 HTML 元素的 style 属性中编写 CSS。适用于单个元素的样式定义。

1
<p style="color: blue; font-size: 20px;">这是一个内联样式的段落。</p>

2. 内部样式表(Internal CSS)

将 CSS 代码写在 HTML 文档的 <head> 部分的 <style> 标签中。适用于单个页面的样式定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html lang="en">
<head>
<style>
p {
color: green;
font-size: 18px;
}
</style>
</head>
<body>
<p>这是一个内部样式表的段落。</p>
</body>
</html>

3. 外部样式表(External CSS)

将 CSS 代码写在独立的 .css 文件中,并通过 <link> 标签引用。适用于多个页面共享样式。

1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<p>这是一个外部样式表的段落。</p>
</body>
</html>

styles.css 文件中:

1
2
3
4
p {
color: purple;
font-size: 22px;
}

3. 选择器

CSS 选择器用于选择特定的 HTML 元素,以应用样式。常见的选择器包括:

  • 元素选择器:选择某种 HTML 元素。

    1
    p { color: red; } /* 选择所有 <p> 元素 */
  • 类选择器:选择带有特定类的元素,类选择器以 . 开头。

    1
    .intro { font-weight: bold; } /* 选择 class="intro" 的元素 */
  • ID 选择器:选择具有特定 ID 的元素,ID 选择器以 # 开头。

    1
    #main-title { color: blue; } /* 选择 id="main-title" 的元素 */
  • 通用选择器:选择页面上的所有元素。

    1
    * { margin: 0; padding: 0; } /* 清除所有元素的外边距和内边距 */
  • 后代选择器:选择嵌套在其他元素内的元素。

    1
    div p { color: green; } /* 选择所有在 <div> 内的 <p> 元素 */
  • 属性选择器 :根据HTML元素的属性来选择元素,选择所有 type 属性为 text<input> 元素。

    1
    2
    3
    input[type="text"] {
    background-color: yellow;
    }

    以上是基本选择器,组合选择器只举一例:

  • 后代选择器 : 选择某个元素的所有后代元素。

    1
    2
    3
    div p {
    color: blue;
    }

4. CSS 属性

一些常见的 CSS 属性如下:

  • 颜色相关

    • color: 文本颜色。
    • background-color: 背景颜色。
    1
    2
    3
    4
    h1 {
    color: blue;
    background-color: yellow;
    }
  • 文本和字体

    • font-size: 字体大小。
    • font-family: 字体系列。
    • font-weight: 字体粗细(如 boldnormal)。
    • text-align: 文本对齐方式(如 leftrightcenter)。
    1
    2
    3
    4
    5
    p {
    font-size: 16px;
    font-family: Arial, sans-serif;
    text-align: center;
    }
  • 布局相关

    • margin: 元素外边距。
    • padding: 元素内边距。
    • width: 宽度。
    • height: 高度。
    1
    2
    3
    4
    5
    6
    div {
    margin: 20px;
    padding: 10px;
    width: 300px;
    height: 200px;
    }
  • 边框

    • border: 边框样式,宽度、颜色和类型可以组合。
    1
    2
    3
    img {
    border: 2px solid black;
    }
  • 显示和定位

    • display: 定义元素的显示方式,如 blockinlinenone
    • position: 定义元素的定位方式,如 relativeabsolutefixed
    1
    2
    3
    4
    5
    6
    7
    8
    9
    .hidden {
    display: none;
    }

    .absolute-box {
    position: absolute;
    top: 50px;
    left: 100px;
    }

5. 层叠与优先级

CSS 的 C(Cascading)代表“层叠”,它表示当多个样式同时作用于一个元素时,浏览器会按以下优先级规则决定使用哪个样式:

  1. 内联样式:直接写在元素内的样式,优先级最高。
  2. ID 选择器:ID 选择器的样式优先级高于类选择器和元素选择器。
  3. 类选择器:类选择器的优先级高于元素选择器。
  4. 元素选择器:元素选择器的优先级最低。

如果多个样式有相同的优先级,后定义的样式会覆盖先定义的样式。

1
2
3
4
5
6
7
p {
color: red; /* 将会被覆盖 */
}

p {
color: blue; /* 最终生效 */
}

6. 响应式设计

CSS 可以通过媒体查询来响应不同设备的屏幕大小。这样可以使网站在不同设备上(如手机、平板、桌面)表现良好。

1
2
3
4
5
@media screen and (max-width: 600px) {
body {
background-color: lightblue;
}
}

7. CSS 框模型(Box Model)

每个 HTML 元素都被看作一个盒子,CSS 盒模型包含以下几个部分:

  • 内容(content):元素的内容。
  • 内边距(padding):内容周围的空白区域。
  • 边框(border):内边距外的边框。
  • 外边距(margin):边框外的空白区域。
1
2
3
4
5
6
div {
width: 200px;
padding: 10px;
border: 5px solid black;
margin: 20px;
}

在这个例子中,div 的内容宽度是 200 px,内边距 10 px,边框 5 px,外边距 20 px。

8. 其他

div是块级元素,会独占一行;span是行内元素,不会独占一行
div中可以嵌套其它的标签,span标签中只能嵌套文本/图片/超链接

js

1. JavaScript

  • 动态内容更新:可以根据用户交互修改网页内容,无需刷新整个页面。
  • 表单验证:在用户提交表单之前,验证输入是否合法。
  • 浏览器控制:可以控制浏览器的行为,比如弹出对话框、导航历史等。
  • 事件驱动编程:响应用户的鼠标点击、键盘按键等操作。
  • 动画和图形:通过 DOM 操作和 CSS 动画,JavaScript 可以实现丰富的视觉效果。

2. JavaScript 语法

1. 基本语法

JavaScript 是一种基于语句的语言,语句以分号 ; 结束(虽然不强制要求,但最好使用)。

  • 变量声明:通过 varletconst 声明变量。
    • var:有函数作用域,较老的变量声明方式。
    • let:有块作用域,适用于现代 JavaScript。
    • const:声明不可变的常量。
1
2
3
var name = "John";   // 使用 var 声明变量
let age = 30; // 使用 let 声明变量
const city = "Paris"; // 使用 const 声明常量

2. 数据类型

  • 数字(Number):整数和浮点数。
  • 字符串(String):用双引号或单引号括起来的文本。
  • 布尔值(Boolean)truefalse
  • 未定义(Undefined):未定义的变量。
  • 空(Null):表示空值。
  • 对象(Object)用于存储键值对或复杂数据结构
1
2
3
4
5
let number = 42;              // 数字
let text = "Hello, World!"; // 字符串
let isTrue = true; // 布尔值
let notDefined; // 未定义变量
let emptyValue = null; // 空值

3. 运算符

  • 算术运算符+(加)、-(减)、*(乘)、/(除)、%(取余)。
  • 赋值运算符=(赋值)、+=(加并赋值)、-=(减并赋值)等。
  • 比较运算符==(相等)、===(严格相等)、!=(不相等)、>< 等。
  • 逻辑运算符&&(与)、||(或)、!(非)。
1
2
3
4
5
6
7
let x = 10;
let y = 5;

console.log(x + y); // 输出 15
console.log(x > y); // 输出 true
console.log(x == "10"); // 输出 true (== 不检查类型)
console.log(x === "10"); // 输出 false (=== 检查类型)

3. 条件语句

  • if… else 语句:根据条件执行不同的代码块。
1
2
3
4
5
6
7
let age = 20;

if (age >= 18) {
console.log("成人");
} else {
console.log("未成年");
}
  • switch 语句:用于对多个条件进行比较。
1
2
3
4
5
6
7
8
9
10
11
12
let color = "blue";

switch (color) {
case "red":
console.log("红色");
break;
case "blue":
console.log("蓝色");
break;
default:
console.log("未知颜色");
}

4. 循环

  • for 循环:用于执行指定次数的循环。
1
2
3
for (let i = 0; i < 5; i++) {
console.log("循环次数: " + i);
}
  • while 循环:只要条件为 true,就会不断执行。
1
2
3
4
5
let i = 0;
while (i < 5) {
console.log("循环次数: " + i);
i++;
}
  • do… while 循环:至少会执行一次,然后根据条件判断是否继续。
1
2
3
4
5
let i = 0;
do {
console.log("循环次数: " + i);
i++;
} while (i < 5);

5. 函数

  • 函数声明
1
2
3
4
5
6
function greet(name) {
return "Hello, " + name;
}

let message = greet("Alice");
console.log(message); // 输出 "Hello, Alice"
  • 函数表达式:可以将函数赋值给变量。
1
2
3
4
5
const sayHello = function(name) {
return "Hello, " + name;
};

console.log(sayHello("Bob")); // 输出 "Hello, Bob"
  • 箭头函数:ES 6 引入的一种简洁写法。
1
2
const add = (a, b) => a + b;
console.log(add(5, 3)); // 输出 8

箭头函数

箭头函数(Arrow Function)是ES6中引入的一种更简洁的书写函数的方法。它使用 => 语法,通常用于简化匿名函数的书写方式。

  • 简洁语法:箭头函数提供了一种更简洁的书写方式,尤其是针对简单函数。
  • this 绑定:箭头函数不创建自己的 this,而是**继承封闭上下文中的 this**。
  • 不适合作为构造函数:箭头函数不能被用作构造函数,也没有 new 关键字的行为。
  • 没有 arguments 对象:箭头函数没有 arguments 对象,但可以使用剩余参数语法来处理参数。
    箭头函数特别适合需要保留上下文 this 的场景,或需要编写简洁代码时的使用。
1
2
3
4
5
6
7
8
9
10
11
12
// 传统函数表达式
let traditionalFunction = function(a, b) {
return a + b;
};

// 箭头函数
let arrowFunction = (a, b) => {
return a + b;
};

// 如果只有一行返回语句,可以省略花括号和`return`
let arrowFunctionShort = (a, b) => a + b;
  • 参数
    如果只有一个参数,参数括号可以省略。

    1
    let singleParam = x => x * 2;
  • 没有参数时
    必须使用空括号。

    1
    let noParam = () => console.log('No parameters');

箭头函数在处理 this 时有一个重要特性:它不会创建自己的 this,而是继承自定义它的上下文。这与传统的函数不同,传统函数的 this 取决于函数是如何调用的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function TraditionalFunction() {
this.value = 1;
setTimeout(function() {
this.value++;
console.log(this.value); // undefined,因为this在此指向全局对象(或undefined,取决于是否使用strict模式)
}, 1000);
}

function ArrowFunction() {
this.value = 1;
setTimeout(() => {
this.value++;
console.log(this.value); // 2,因为箭头函数的this是继承自ArrowFunction中的this
}, 1000);
}

new TraditionalFunction(); // 输出 NaN 或 undefined
new ArrowFunction(); // 输出 2

箭头函数与传统函数的另一个不同点是,箭头函数不能作为构造函数(即不能用 new 关键字来调用),而传统函数可以。

1
2
3
4
5
6
7
8
let ArrowFunction = () => {};
let TraditionalFunction = function() {};

// 传统函数可以用new关键字创建实例
let obj1 = new TraditionalFunction(); // 允许

// 箭头函数不允许使用new
let obj2 = new ArrowFunction(); // 错误:ArrowFunction is not a constructor

传统函数有一个 arguments 对象,表示传递给函数的所有参数。箭头函数没有自己的 arguments,但可以通过剩余参数语法来获取参数。

1
2
3
4
5
6
7
8
9
10
11
let traditionalFunction = function() {
console.log(arguments);
};

traditionalFunction(1, 2, 3); // 输出:{0: 1, 1: 2, 2: 3}

let arrowFunction = (...args) => {
console.log(args);
};

arrowFunction(1, 2, 3); // 输出:[1, 2, 3]

arguments对象

arguments 对象是 JavaScript 中所有非箭头函数内置的一个类数组对象,包含了函数调用时传入的所有参数。它允许你访问传递给函数的参数,而不需要明确在函数声明中定义它们。

  • arguments 是一个类数组对象,包含了传给函数的所有参数。
  • 它对处理不确定数量的参数非常有用。
  • arguments 在 ES 6 中已经被 ... 剩余参数语法部分取代,后者更灵活方便。
  • 它不能在箭头函数中使用,在这种情况下,它会从外层上下文继承。
    arguments 对象虽然经典,但在现代 JavaScript 中,通常更推荐使用 剩余参数 (...rest) 来处理可变数量的参数,因为它提供了更清晰的语法和更强大的功能。

特点:

  1. 类数组对象
    • arguments 是一个类似数组的对象,它有 length 属性,但不是真正的数组,因此没有数组的方法(如 push, forEach 等)。然而,你可以通过索引来访问各个参数。
  2. 动态性
    • 无论函数定义了多少个参数,arguments 对象都会包含函数调用时传入的所有参数(即使传入的参数比函数声明的参数多或少)。
  3. 不可用于箭头函数
    • arguments 对象在箭头函数中不存在。箭头函数不会绑定自己的 arguments 对象,它会从它的封闭上下文中继承 arguments
1
2
3
4
5
6
7
function exampleFunction() {
console.log(arguments);
console.log(arguments[0]); // 访问第一个参数
console.log(arguments.length); // 参数个数
}

exampleFunction(1, "Hello", true);

输出:

1
2
3
[Arguments] { '0': 1, '1': 'Hello', '2': true }
1
3

应用场景:

  1. 处理可变参数个数的函数
    arguments 对象经常用于函数的参数个数不固定时,特别是在 ES 6 之前没有默认参数和剩余参数的场景下。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function sum() {
    let total = 0;
    for (let i = 0; i < arguments.length; i++) {
    total += arguments[i];
    }
    return total;
    }

    console.log(sum(1, 2, 3, 4)); // 输出:10
  2. 与剩余参数对比
    在 ES 6 引入的剩余参数(Rest Parameters)后,arguments 对象的使用有所减少。剩余参数可以将传入的参数作为一个真正的数组,而不是类数组对象,这更加方便。

    • **使用 arguments**:

      1
      2
      3
      4
      5
      6
      7
      8
      function multiply() {
      let result = 1;
      for (let i = 0; i < arguments.length; i++) {
      result *= arguments[i];
      }
      return result;
      }
      console.log(multiply(2, 3, 4)); // 输出:24
    • 使用剩余参数

      1
      2
      3
      4
      function multiply(...args) {
      return args.reduce((product, current) => product * current, 1);
      }
      console.log(multiply(2, 3, 4)); // 输出:24

    ...args 是一个真正的数组,可以直接使用数组方法如 reduce,而不需要像 arguments 那样手动迭代。

6. 事件和 DOM 操作

在 JavaScript 中,事件DOM 操作 是构建动态网页的核心。事件使网页能够对用户的交互(如点击、键盘输入等)作出响应,而 DOM(Document Object Model) 操作则允许 JavaScript 动态地更改网页的内容和结构。

  • 事件:通过事件处理器监听用户行为(如点击、按键等),并通过 addEventListener() 绑定事件。事件对象可以提供详细的事件信息。
  • DOM 操作:允许我们动态地获取、修改、创建、删除页面中的 HTML 元素,进而实现动态的网页交互。

一、事件

事件 是用户或浏览器执行的动作,例如鼠标点击、按键按下、窗口加载等。

  1. 常见事件类型
  • 鼠标事件

    • click:当用户点击元素时触发。
    • dblclick:当用户双击元素时触发。
    • mouseover:当鼠标移到元素上时触发。
    • mouseout:当鼠标移出元素时触发。
    • mousedown / mouseup:鼠标按下和释放时触发。
  • 键盘事件

    • keydown:按下键盘按键时触发。
    • keyup:释放按键时触发。
  • 表单事件

    • submit:表单提交时触发。
    • change:表单元素的值发生变化时触发(如 <input><select>)。
  • 窗口事件

    • load:页面加载完成时触发。
    • resize:浏览器窗口大小发生变化时触发。
    • scroll:当页面或元素滚动时触发。
  1. 事件处理器(Event Handlers)

事件处理器(或事件监听器)是指在特定事件发生时执行的函数。有三种常见的方式来添加事件处理器:

方法 1:HTML 内联事件处理

将 JavaScript 直接写在 HTML 元素的事件属性中。

1
<button onclick="alert('你点击了按钮!')">点击我</button>

方法 2:DOM 的 onEvent 属性

通过 JavaScript 设置元素的 onEvent 属性(例如 onclick)来添加事件处理。

1
2
3
4
let button = document.querySelector("button");
button.onclick = function() {
alert("按钮被点击了");
};

方法 3:addEventListener() 方法

这是推荐的方式,允许我们为同一事件添加多个事件处理器,并能更好地控制事件(如移除事件处理器等)。

1
2
3
4
let button = document.querySelector("button");
button.addEventListener("click", function() {
alert("按钮被点击了");
});

使用 addEventListener() 的好处:

  • 可以为同一个元素添加多个事件监听器。
  • 可以在需要时轻松移除事件处理器。
  • 支持事件冒泡和捕获。
  1. 事件对象(Event Object)

当事件被触发时,浏览器会生成一个事件对象,该对象包含了与事件相关的详细信息,例如触发事件的元素、鼠标的坐标、按键状态等。

  • 常用属性:
    • target:事件触发的元素。
    • type:事件类型,如 clickkeydown
    • key:当处理键盘事件时,表示按下的键。
    • clientX / clientY:鼠标事件中,表示鼠标点击时的 X 和 Y 坐标。
1
2
3
document.addEventListener("click", function(event) {
console.log("点击位置 X: " + event.clientX + ",Y: " + event.clientY);
});
  1. 事件传播模型

事件传播是指事件从触发源开始如何传播到其他相关元素。JavaScript 中有三种传播阶段:

  • 捕获阶段:事件从文档的根元素向事件目标传播。
  • 目标阶段:事件到达目标元素(触发事件的元素)。
  • 冒泡阶段:事件从目标元素向上冒泡,经过其祖先元素。

事件监听器默认在冒泡阶段执行,但可以通过 addEventListener 的第三个参数将监听器绑定在捕获阶段。

1
2
3
document.querySelector("div").addEventListener("click", function(event) {
console.log("DIV 捕获阶段");
}, true); // 第三个参数为 true,表示在捕获阶段执行

二、DOM 操作

DOM(Document Object Model) 是网页的编程接口,表示页面的结构。通过 DOM,我们可以动态地修改、创建、删除页面中的元素,改变样式,响应用户交互等。

  1. 获取 DOM 元素
    获取元素:
  • **getElementById()**:通过元素的 ID 获取元素。

    1
    let element = document.getElementById("myElement");
  • **getElementsByClassName()**:通过类名获取元素集合。

    1
    let elements = document.getElementsByClassName("myClass");
  • **getElementsByTagName()**:通过标签名获取元素集合。

    1
    let elements = document.getElementsByTagName("p");
  • **querySelector()**:通过 CSS 选择器获取第一个匹配的元素。

    1
    let element = document.querySelector(".myClass");
  • **querySelectorAll()**:通过 CSS 选择器获取所有匹配的元素。

    1
    let elements = document.querySelectorAll(".myClass");
  1. 修改 DOM 元素

修改内容

  • **innerHTML**:更改元素的 HTML 内容。

    1
    2
    let div = document.getElementById("myDiv");
    div.innerHTML = "<p>新内容</p>";
  • **textContent**:更改元素的纯文本内容(不会解析 HTML)。

    1
    2
    let div = document.getElementById("myDiv");
    div.textContent = "新文本内容";

    修改属性

  • **setAttribute()**:设置元素的属性。

    1
    2
    let img = document.querySelector("img");
    img.setAttribute("src", "newImage.jpg");
  • **removeAttribute()**:移除元素的属性。

    1
    2
    let img = document.querySelector("img");
    img.removeAttribute("alt");
  • 直接修改属性:可以通过点语法直接修改元素的属性。

    1
    2
    let input = document.querySelector("input");
    input.type = "password";

修改样式

可以通过 style 属性直接修改元素的内联样式:

1
2
3
let div = document.getElementById("myDiv");
div.style.color = "blue";
div.style.backgroundColor = "yellow";
  1. 创建和删除元素

创建新元素

  • **createElement()**:创建一个新的 DOM 元素。
    1
    2
    let newElement = document.createElement("div");
    newElement.textContent = "这是一个新元素";

插入元素

  • **appendChild()**:将新元素添加为某个元素的子元素。

    1
    2
    let parentElement = document.getElementById("parent");
    parentElement.appendChild(newElement);
  • **insertBefore()**:在指定子元素前插入新元素。

    1
    2
    let firstChild = parentElement.firstChild;
    parentElement.insertBefore(newElement, firstChild);

删除元素

  • **removeChild()**:从父元素中删除子元素。

    1
    2
    3
    let parentElement = document.getElementById("parent");
    let child = document.getElementById("child");
    parentElement.removeChild(child);
  • **remove()**:直接删除当前元素。

    1
    2
    let element = document.getElementById("myElement");
    element.remove();
  1. 事件与 DOM 操作结合

例如,点击按钮后动态生成一个新的段落:

1
2
3
4
5
6
7
8
9
10
<button id="addParagraph">添加段落</button>
<div id="content"></div>

<script>
document.getElementById("addParagraph").addEventListener("click", function() {
let newParagraph = document.createElement("p");
newParagraph.textContent = "这是一个新段落";
document.getElementById("content").appendChild(newParagraph);
});
</script>

点击按钮时,新的段落会动态添加到 div 中。

7. 数组和对象

1. 数组

1
2
let fruits = ["apple", "banana", "cherry"];
console.log(fruits[1]); // 输出 "banana"
  • push():在数组末尾添加元素。
  • pop():移除数组末尾的元素。
  • length:获取数组长度。

2. 对象:存储键值对,可以表示一个实体及其属性。

1
2
3
4
5
6
7
8
let person = {
name: "John",
age: 30,
city: "New York"
};

console.log(person.name); // 输出 "John"
person.age = 31; // 修改对象属性

8. 异步编程

允许程序在等待较长时间的操作(如文件读取、网络请求)完成时,继续执行其他任务,而不必阻塞程序的执行流。

回调函数:函数可以作为参数传递到另一个函数中,在异步操作完成后执行。

1
2
3
setTimeout(function() {
console.log("1秒后执行");
}, 1000);
1
2
3
4
5
6
7
8
9
10
11
function fetchData(callback) {
setTimeout(() => {
let data = "数据加载完成";
callback(data); // 异步任务完成后调用回调函数
}, 2000);
}

fetchData((result) => {
console.log(result); // 输出 "数据加载完成"
});

但它存在一个问题,即回调地狱(Callback Hell):当多个异步任务依赖于彼此时,回调函数会不断嵌套,代码难以维护和阅读。

Promise:用于处理异步操作的对象。

  1. 解决回调地狱Promise 提供了链式调用 . then () 的方式,避免了多层嵌套的回调函数。
  2. 增强可读性:通过链式调用,代码逻辑更加线性和直观,易于理解。
  3. 错误处理机制:通过 . catch () 统一处理异步操作中的错误。
  4. 更灵活的异步控制:通过 Promise.all ()Promise.race () 等方法,控制多个异步任务的执行方式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
let promise = new Promise(function(resolve, reject) {
let success = true;
if (success) {
resolve("操作成功!");
} else {
reject("操作失败!");
}
});

promise.then(function(result) {
console.log(result); // 输出 "操作成功!"
}).catch(function(error) {
console.log(error);
});

Promise 是 JavaScript 中用于处理异步操作的对象,它提供了一种更优雅、简洁的方式来处理异步任务,避免了传统的回调函数(callback)方式容易导致的“回调地狱”(callback hell)问题。Promise 可以通过 .then().catch() 方法进行链式调用,并提供了错误处理机制。

Promise 是一个代表异步操作最终完成或失败的对象。它有三种状态:

  • 待定(Pending):异步操作尚未完成,Promise 还没有被解决或拒绝。
  • 已解决(Fulfilled):异步操作成功完成,Promise 被解决,返回结果。
  • 已拒绝(Rejected):异步操作失败,Promise 被拒绝,返回错误。

Promise 的基本语法

  • **resolve**:表示异步操作成功时调用,通常会传递成功的结果。
  • **reject**:表示异步操作失败时调用,通常会传递失败的原因或错误信息。

模拟一个异步任务(例如,从服务器获取数据)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let myPromise = new Promise(function(resolve, reject) {
// 模拟一个耗时的异步操作,使用 setTimeout
setTimeout(function() {
let success = true; // 模拟成功或失败的条件
if (success) {
resolve("数据获取成功");
} else {
reject("数据获取失败");
}
}, 2000);
});

// 使用 .then() 处理成功的结果,使用 .catch() 处理失败
myPromise
.then(function(result) {
console.log(result); // 输出: "数据获取成功"
})
.catch(function(error) {
console.log(error); // 输出: "数据获取失败"(如果失败)
});

myPromise 是一个 Promise 对象,它表示一个异步操作,模拟了 2 秒后异步任务的完成。根据 success 的值决定是否调用 resolve(成功)或 reject(失败)。我们可以使用 .then() 来处理成功的结果,使用 .catch() 来处理失败的情况。

Promise 状态转换
Promise 的状态一旦从“待定”变为“已解决”或“已拒绝”,就不能再变更。这意味着:

  • 如果 Promise 被解决(resolve),它的结果值就固定下来了,不会再变化。
  • 如果 Promise 被拒绝(reject),它的错误信息也固定了。

无论 Promise 成功还是失败,它只会改变一次。

链式调用 .then()

Promise 的一个强大特性是 .then() 方法可以链式调用。当一个异步操作成功完成并返回结果时,可以通过 .then() 来处理这个结果。如果 .then() 方法返回一个新的 Promise,那么可以继续链式调用后续的 .then()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let promise = new Promise(function(resolve, reject) {
setTimeout(() => resolve(10), 1000); // 1 秒后返回结果 10
});

promise
.then(function(result) {
console.log(result); // 输出: 10
return result * 2; // 返回新的值 20
})
.then(function(result) {
console.log(result); // 输出: 20
return result * 3; // 返回新的值 60
})
.then(function(result) {
console.log(result); // 输出: 60
});

在这个例子中,每个 .then() 的返回值会传递给下一个 .then(),形成链式结构,依次处理结果。这种链式调用机制让异步操作之间的依赖关系更加清晰。

错误处理:.catch() 和 .finally()

  1. .catch() 方法
    .catch() 用于捕获 Promise 链中的错误。如果 Promise 被拒绝,或者在 .then() 中发生了错误,.catch() 都会捕获到这些错误。
1
2
3
4
5
6
7
8
9
10
11
let promise = new Promise(function(resolve, reject) {
setTimeout(() => reject("网络请求失败"), 1000); // 模拟异步操作失败
});

promise
.then(function(result) {
console.log(result); // 不会被执行
})
.catch(function(error) {
console.log("发生错误: " + error); // 输出: "发生错误: 网络请求失败"
});
  1. .finally() 方法
    .finally() 无论 Promise 成功或失败,都会执行。它用于编写在 Promise 结束后都需要执行的逻辑,比如关闭加载动画或清理资源。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
let promise = new Promise (function (resolve, reject) {
setTimeout (() => resolve ("操作成功"), 1000);
});

promise
.then (function (result) {
console.log (result); // 输出: 操作成功
})
.catch (function (error) {
console.log (error); // 不会被执行
})
.finally (function () {
console.log ("操作结束"); // 无论成功或失败,都会执行
});

Promise.all () 并行执行多个异步操作

Promise.all () 用于并行执行多个 Promise,等待所有 Promise 都成功后再返回。如果其中一个 Promise 被拒绝,整个 Promise.all () 都会被拒绝。

语法:

1
2
3
4
5
6
7
8
9
Promise.all ([promise 1, promise 2, promise 3])
.then (function (results) {
// 所有 Promise 都成功时执行
console.log (results); // 是一个包含每个 Promise 结果的数组
})
.catch (function (error) {
// 只要有一个 Promise 被拒绝,执行此处
console.log (error);
});

Promise.race ():竞争模式

Promise.race () 类似于比赛,它会返回第一个解决或拒绝的 Promise,无论是成功还是失败。也就是说,它会返回最快执行的那个 Promise 的结果或错误。

1
2
3
4
5
6
7
8
9
10
11
let promise 1 = new Promise ((resolve) => setTimeout (() => resolve ("结果 1"), 1000));
let promise 2 = new Promise ((resolve) => setTimeout (() => resolve ("结果 2"), 500));
let promise 3 = new Promise ((resolve) => setTimeout (() => resolve ("结果 3"), 1500));

Promise.race ([promise 1, promise 2, promise 3])
.then (function (result) {
console.log (result); // 输出: "结果 2" (因为它最快完成)
})
.catch (function (error) {
console.log ("某个 Promise 失败", error);
});

Promise.resolve () 和 Promise.reject ()

  1. Promise.resolve ()
    Promise.resolve () 方法返回一个已解决的 Promise,可以快速返回一个成功的结果。
1
2
3
4
5
let promise = Promise.resolve ("快速成功的结果");

promise.then (function (result) {
console.log (result); // 输出: 快速成功的结果
});
  1. Promise.reject ()
    Promise.reject () 方法返回一个已拒绝的 Promise,用于快速返回一个失败的结果。

示例:

1
2
3
4
5
let promise = Promise.reject ("快速失败的原因");

promise.catch (function (error) {
console.log (error); // 输出: 快速失败的原因
});

async/await:基于 Promise的语法糖,使异步代码更加直观。

async 用于声明一个异步函数,而 await 用于等待一个异步操作完成。使用 await 可以让代码看起来像是同步执行的,避免了复杂的 then 链式调用,提升了代码的可读性。

  • async 函数会返回一个 Promise 对象。
  • await 只能在 async 函数中使用,它会暂停函数的执行,等待 Promise 完成。
    1
    2
    3
    4
    5
    6
    async function fetchData() {
    let response = await fetch("https://api.example.com/data");
    let data = await response.json();
    console.log(data);
    }
    fetchData();
1
2
3
4
5
6
7
8
9
10
11
async function fetchData(){
try{
let result1=await asyncTask1();
let result2=await asyncTask2(result1);
let result3=await asyncTask3(result2);
console.log("所有任务完成",result3);
}catch(error){
console.log("任务失败",error);
}
}
fetchData();
1
2
3
4
5
6
7
8
async function myFunction(){
let promise=new Promise((resolve,reject)=>{
setTimeout(()=>resolve("数据已获取"),2000);
});
let result =await promise;
console.log(result);
}
myFunction();

常见的异步操作

  • 定时器:如 setTimeoutsetInterval,用于延时和周期性任务。
  • 网络请求:如 fetchXMLHttpRequest,用于异步数据加载。
  • 文件操作:在Node.js中,文件系统操作通常是异步的。
作者

zyh

发布于

2024-10-05

更新于

2024-11-10

许可协议

评论