JavaScript 前端学习指南
JavaScript是当今Web开发的核心语言之一。作为前端开发的基石,掌握JavaScript有助于开发者构建动态、交互丰富的网页应用程序。本文将详细介绍JavaScript的基本语法、DOM和BOM的使用、接口请求、最新的ES6+特性,以及一些重要的概念如变量提升、事件冒泡与捕获、作用域和原型。
JavaScript的基本语法详解
JavaScript的基本语法是任何开发者必须首先掌握的重要知识。它为我们与浏览器进行交互提供了强大功能,同时也是理解更复杂概念的基础。以下是对JavaScript基本语法的详细解析:
变量声明
JavaScript有三种主要的变量声明方式:var
、let
和const
。
-
var
:可以声明一个全局变量或函数级变量,具有变量提升特性。var greeting = "Hello, World!"; console.log(greeting); // 输出 "Hello, World!"
-
let
:用于声明块级局部变量,适合在if
、for
等代码块中使用。let count = 10; if (true) { let count = 20; console.log(count); // 输出 20 } console.log(count); // 输出 10
-
const
:用于声明常量,一旦赋值不能改变。适用于不需要修改的值。const pi = 3.14159; // pi = 3.14; // 会导致错误
数据类型
JavaScript支持多种数据类型,包括:
-
原始类型(Primitive Types):
number
、string
、boolean
、undefined
、null
、symbol
、bigint
。let age = 25; // number let name = "Alice"; // string let isStudent = true; // boolean let data; // undefined let noValue = null; // null
-
对象类型(Object Types):对象、数组、函数等。
let person = { name: "Alice", age: 25 }; // 对象 let numbers = [1, 2, 3]; // 数组
操作符
JavaScript提供了多种操作符,用于操作数据:
-
算术操作符:
+
,-
,*
,/
,%
,++
,--
let sum = 10 + 5; // 15 let increment = 5; increment++; // 6
-
比较操作符:
==
,===
,!=
,!==
,<
,>
,<=
,>=
console.log(10 === '10'); // false (严格相等) console.log(10 == '10'); // true (非严格相等)
-
逻辑操作符:
&&
,||
,!
let isValid = true; let isComplete = false; console.log(isValid && isComplete); // false console.log(isValid || isComplete); // true
控制结构
JavaScript使用多种控制结构来影响代码执行流程:
-
条件语句:
if
,else if
,else
if (age >= 18) { console.log("Adult"); } else { console.log("Minor"); }
-
循环语句:
for
,while
,do...while
for (let i = 0; i < 5; i++) { console.log(i); // 输出 0 到 4 } let i = 0; while (i < 5) { console.log(i); i++; }
-
switch
语句:用于执行多分支选择。let grade = 'A'; switch (grade) { case 'A': console.log("Excellent"); break; case 'B': console.log("Good"); break; default: console.log("Needs Improvement"); }
函数
函数是JavaScript中复用代码的主要方式:
-
函数声明:
function greet(name) { return 'Hello ' + name; } console.log(greet('Alice')); // 输出 "Hello Alice"
-
函数表达式:
const greet = function(name) { return 'Hello ' + name; };
-
箭头函数: (ES6引入的简洁语法)
const add = (a, b) => a + b; console.log(add(5, 10)); // 输出 15
模板字符串
模板字符串使字符串操作更加直观和强大:
- 使用反引号 (
`
) 包围,并且可以内嵌任意表达式。const name = 'Alice'; console.log(`Hello, ${name}!`); // 输出 "Hello, Alice!"
JavaScript中的DOM&BOM详解
JavaScript不仅仅是一种计算工具,它还可以与浏览器及其页面内容进行动态交互。这得益于DOM(文档对象模型)和BOM(浏览器对象模型)的全面支持。这两者在让页面变得生动且与用户互动的过程中扮演着重要角色。
DOM(文档对象模型)
DOM是一个用于操作和访问HTML网页结构的接口。它将整个网页表示为一个树形结构,树中的每个节点都代表着文档中的一部分(例如元素、属性、文本等)。
1. DOM 节点操作
-
访问元素:
-
getElementById
:通过元素的ID获取元素。const header = document.getElementById('header');
-
getElementsByClassName
:通过类名获取元素列表。const items = document.getElementsByClassName('item');
-
getElementsByTagName
:通过标签名获取元素列表。const paragraphs = document.getElementsByTagName('p');
-
querySelector
和querySelectorAll
:支持CSS选择器的方式获取元素。const main = document.querySelector('.main'); const listItem = document.querySelectorAll('.list-item');
-
-
修改元素内容和属性:
-
修改文本内容:
header.textContent = "Welcome to My Website";
-
修改HTML内容:
main.innerHTML = "<h2>Main Content</h2>";
-
修改属性:
let image = document.querySelector('img'); image.src = "new-image.jpg";
-
-
创建和插入节点:
const newDiv = document.createElement('div'); newDiv.textContent = "I'm a new div!"; document.body.appendChild(newDiv);
2. DOM 事件处理
-
事件监听:处理用户和浏览器的交互最直接的方式。
document.getElementById('myButton').addEventListener('click', function() { alert('Button clicked!'); });
常用事件类型有:
click
、mouseover
、keydown
、load
等。
BOM(浏览器对象模型)
BOM 提供了一系列独立于页面内容的浏览器功能接口。通过这些接口,开发者可以操控浏览器窗口、与用户进行更广泛的交互。
1. 操作浏览器窗口
-
打开和关闭窗口:
const newWindow = window.open('https://example.com', '_blank'); newWindow.close();
-
窗口大小和位置:
console.log(window.innerWidth); // 浏览器窗口的宽度 console.log(window.innerHeight); // 浏览器窗口的高度 // 移动窗口 window.moveTo(100, 100); // 调整窗口大小 window.resizeTo(800, 600);
2. 操作浏览器历史
- 浏览历史导航:
window.history.back(); // 后退一页 window.history.forward(); // 前进一页 window.history.go(-2); // 移动到历史中的特定页面位置
3. 浏览器环境信息
-
Navigator 对象:包含有关浏览器的信息
console.log(navigator.userAgent); console.log(navigator.language);
-
Location 对象:包含有关当前URL的信息,可以用来重新加载或更改页面
console.log(window.location.href); // 当前URL window.location.href = 'https://anotherdomain.com'; // 跳转到新URL
通过DOM和BOM,JavaScript可以动态地改变网页内容和与浏览器进行深入互动。这种能力使得JavaScript成为构建动态和交互式Web应用程序不可或缺的一部分。。
JavaScript中的接口请求:Ajax与Fetch
在现代Web应用中,与服务器进行数据交换是至关重要的一部分。JavaScript提供了多种方式来执行异步的HTTP请求,其中最常用的是Ajax和Fetch API。这两者允许网页在不重新加载的情况下更新数据,从而提升用户体验。
Ajax(Asynchronous JavaScript and XML)
Ajax是一个技术集合,它允许在不重新加载整个网页的情况下,通过JavaScript与服务器进行通信。虽然“XML”是其名称的一部分,但现代应用更多用JSON格式进行数据交换。
1. 使用XMLHttpRequest对象
XMLHttpRequest是执行Ajax请求的传统方式,可以发送、接收和处理HTTP请求。
-
创建 XMLHttpRequest 对象
let xhr = new XMLHttpRequest();
-
配置请求
使用.open()
方法配置请求的方法类型和目标URL。xhr.open('GET', 'https://api.example.com/data', true);
-
处理响应
使用.onload
事件处理响应数据。xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { console.log(xhr.responseText); // 输出响应文本 } else { console.error('Request failed with status', xhr.status); } };
-
发送请求
xhr.send();
-
处理错误
onerror
可以用于处理请求错误。xhr.onerror = function() { console.error('Network error'); };
-
发送数据
通过POST
方法发送数据。xhr.open('POST', 'https://api.example.com/data', true); xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); xhr.send(JSON.stringify({ key: 'value' }));
Fetch API
Fetch API是现代浏览器提供的一种更简单、更强大的方法来进行网络请求。Fetch使用Promise语法,使异步处理更加直观。
-
基本语法
fetch('https://api.example.com/data') .then(response => { if (!response.ok) { throw new Error('Network response was not ok ' + response.statusText); } return response.json(); }) .then(data => console.log(data)) .catch(error => console.error('Fetch error:', error));
-
发送POST请求
使用Fetch发送POST请求时,需要配置请求头和请求体。fetch('https://api.example.com/data', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ key: 'value' }) }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Fetch error:', error));
-
处理不同的数据类型
Fetch API可以请求和处理多种类型的数据,例如文本、JSON、Blob等。fetch('https://api.example.com/data') .then(response => response.blob()) .then(blob => { // 处理 blob 数据 });
-
请求初始化选项
Fetch API允许使用第二个参数(init对象)来控制请求的各种属性。const options = { method: 'GET', // POST, DELETE, etc. headers: { 'Content-Type': 'application/json' }, mode: 'cors', // 跨域请求 cache: 'default' // no-cache, reload, force-cache, etc. }; fetch('https://api.example.com/data', options) .then(response => response.json()) .then(data => console.log(data));
Fetch API的出现大大简化了异步请求的流程,减少了出错的可能性,并提高了代码的可读性。与此同时,XMLHttpRequest仍然是一个支持范围极广的传统方法,在某些特定情况下可能仍然需要使用。
通过熟练掌握Ajax和Fetch,你可以创建高效的实时数据应用,提高应用程序的响应性和用户体验。
ES6+(ECMAScript 2015及其后续版本)详细介绍
ECMAScript 6(简称ES6),也被称为ECMAScript 2015,是JavaScript语言的一个重大更新版本。它引入了许多新的特性和语法糖,极大地增强了JavaScript的功能和易用性。在ES6之后,还有ES7(2016)、ES8(2017)等后续版本继续对语言进行发展和扩展。以下是ES6及其后续版本中的一些重要特性:
1. 块级作用域(let和const)
-
let:声明块级作用域变量,避免了
var
带来的变量提升问题。let x = 10; if (true) { let x = 20; console.log(x); // 20 } console.log(x); // 10
-
const:声明常量,不可重新赋值,适合不变的变量。
const y = 30; // y = 40; // 会产生错误
2. 箭头函数
箭头函数提供了一种更简洁的函数定义方式,并保留了this
关键字的指向。
const add = (a, b) => a + b;
console.log(add(2, 3)); // 5
注意:箭头函数没有自己的this
,它会捕获在其上下文中定义的this
。
3. 模板字符串
允许嵌入表达式和多行字符串,增强了字符串处理的能力。
let name = "World";
let greeting = `Hello, ${name}!`;
console.log(greeting); // "Hello, World!"
4. 解构赋值
解构赋值使得从数组和对象中提取数据更加简洁。
-
数组解构:
let [a, b] = [1, 2]; console.log(a); // 1 console.log(b); // 2
-
对象解构:
let person = { name: 'Alice', age: 25 }; let { name, age } = person; console.log(name); // "Alice" console.log(age); // 25
5. 默认参数
允许为函数参数设置默认值。
function multiply(x, y = 1) {
return x * y;
}
console.log(multiply(5)); // 5
6. 扩展运算符
扩展运算符...
用于展开数组或对象。
-
在数组中:
let arr1 = [1, 2, 3]; let arr2 = [...arr1, 4, 5]; console.log(arr2); // [1, 2, 3, 4, 5]
-
在对象中:
let obj1 = { a: 1, b: 2 }; let obj2 = { ...obj1, c: 3 }; console.log(obj2); // { a: 1, b: 2, c: 3 }
7. 类与继承
JavaScript借鉴面向对象语言,引入了class
语法用于创建类。
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
speak() {
console.log(`${this.name} barks.`);
}
}
let d = new Dog("Rover");
d.speak(); // "Rover barks."
8. Promise
Promise是异步编程的一种解决方案,简化了多层回调的问题。
let promise = new Promise((resolve, reject) => {
// 执行异步操作
let success = true;
if (success) {
resolve("Operation successful");
} else {
reject("Operation failed");
}
});
promise.then(message => {
console.log(message);
}).catch(error => {
console.log(error);
});
9. 模块化
import
和export
允许在多个JavaScript文件中拆分和共享代码。
-
模块导出:
export const square = x => x * x;
-
模块导入:
import { square } from './math'; console.log(square(4)); // 16
10.更多特性和改进
在ES6之后,JavaScript每年都会发布新的版本,增添或改进一些特性,比如:
-
includes()
方法:用于数组和字符串检查元素或子串是否存在。let arr = [1, 2, 3]; console.log(arr.includes(2)); // true
-
async/await
:在ES2017中引入,简化了异步操作的写法,使之更接近同步代码。async function fetchData() { let response = await fetch('https://api.example.com/data'); let data = await response.json(); console.log(data); } fetchData();
-
Object.entries()
和Object.values()
:用于遍历对象属性。let obj = { foo: 'bar', baz: 42 }; console.log(Object.entries(obj)); // [["foo", "bar"], ["baz", 42]] console.log(Object.values(obj)); // ["bar", 42]
ES6+的这些新增特性提高了代码的简洁性、可读性和性能,同时也使JavaScript从一个简单的脚本语言发展成为一个功能强大的现代编程语言。通过掌握这些特性,开发者可以更高效地编写出结构良好、可维护性强的代码。
JavaScript中的关键概念详解
在学习和使用JavaScript时,理解一些核心概念是至关重要的。这些概念包括变量提升、事件冒泡与捕获、作用域以及原型链等。掌握这些概念有助于编写更高效、更具可读性的代码。
1. 变量提升(Hoisting)
变量提升是JavaScript的一个特性,它将变量声明提升到其作用域的顶部。这意味着在代码执行之前,变量和函数声明会被“提升”到当前作用域的顶部。
-
变量提升的例子:
console.log(a); // 输出: undefined var a = 5; console.log(a); // 输出: 5
在上面的代码中,
var a
被提升到作用域的顶部,因此在声明之前访问它不会导致错误,但值为undefined
。 -
函数提升:
函数声明也会被提升,因此可以在声明之前调用函数。console.log(greet()); // 输出: "Hello" function greet() { return "Hello"; }
注意:
let
和const
声明的变量不会被提升,或者更准确地说,它们被提升但不初始化,因此在声明之前访问它们会导致ReferenceError
。
2.事件冒泡与捕获详解
事件冒泡和捕获是JavaScript事件处理机制中的两个重要概念。它们描述了事件在DOM树中传播的方式。在处理用户的交互(如点击、键盘输入等)时,理解这些概念非常重要。
1. 事件传播的阶段
JavaScript中的事件传播主要分为三个阶段:
-
捕获阶段(Capturing Phase):
- 事件从
document
对象开始,逐层向下传播,直到到达事件的目标元素。 - 在这个阶段,可以通过在监听事件时设置第三个参数为
true
来捕获事件。例如:element.addEventListener('click', handler, true)
.
- 事件从
-
目标阶段(Target Phase):
- 事件到达目标元素,并在那里触发事件处理程序。
-
冒泡阶段(Bubbling Phase):
- 事件从目标元素开始,逐层向上返回到
document
对象。 - 这是默认的事件处理行为。在这个阶段,可以简单地使用
element.addEventListener('click', handler)
。
- 事件从目标元素开始,逐层向上返回到
2. 具体例子
我们通过一个简单的HTML结构和JavaScript代码来演示这两个概念。
<!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 id="parent" style="padding: 20px; background-color: lightblue;">
Parent
<button id="child">Click Me!</button>
</div>
<script>
// 父元素的点击事件
document.getElementById('parent').addEventListener('click', () => {
console.log('Parent clicked!');
});
// 子元素的点击事件
document.getElementById('child').addEventListener('click', () => {
console.log('Child clicked!');
});
// 使用捕获阶段设置父元素的点击事件
document.getElementById('parent').addEventListener('click', () => {
console.log('Parent clicked (capturing)!');
}, true); // 设置为捕获阶段
</script>
</body>
</html>
3. 测试事件传播
-
点击按钮:当你点击按钮时,会产生以下输出(假设先设置了捕获事件):
Parent clicked (capturing)!
(在捕获阶段)Child clicked!
(在目标阶段)Parent clicked!
(在冒泡阶段)
-
没有使用捕获:如果不设置为捕获(即不传递第三个参数),点击按钮的输出会是:
Child clicked!
(在目标阶段)Parent clicked!
(在冒泡阶段)
事件处理总结
-
冒泡是指事件从目标元素向上传播到父元素。它是事件处理的默认行为。
-
捕获是指事件从父元素向下传播到目标元素。为了使用捕获机制,需在事件监听器中设置第三个参数为
true
。
3. 作用域(Scope)
作用域决定了代码中变量的可访问性。JavaScript有三种主要的作用域:全局作用域、函数作用域和块级作用域。
-
全局作用域:
在代码的任何地方都可以访问的变量。var globalVar = "I am global"; function checkScope() { console.log(globalVar); // "I am global" }
-
函数作用域:
在函数内声明的变量只能在该函数内访问。function localScope() { var localVar = "I am local"; console.log(localVar); // "I am local" } // console.log(localVar); // 报错:localVar未定义
-
块级作用域:
ES6引入了let
和const
,使得块级作用域成为可能。if (true) { let blockVar = "I am block-scoped"; console.log(blockVar); // "I am block-scoped" } // console.log(blockVar); // 报错:blockVar未定义
4. 原型链(Prototype Chain)
JavaScript使用原型链实现继承。每个对象都有一个原型对象,继承自其原型对象的属性和方法。
-
原型链的基本概念:
function Person(name) { this.name = name; } Person.prototype.greet = function() { console.log(`Hello, my name is ${this.name}`); }; const alice = new Person('Alice'); alice.greet(); // "Hello, my name is Alice"
在这个例子中,
alice
对象继承了Person
的原型对象上的greet
方法。 -
继承链:
当访问一个对象的属性时,如果对象本身没有这个属性,JavaScript会沿着原型链向上查找,直到找到该属性或到达原型链的顶层(null
)。 -
Object.create
:
可以使用Object.create
方法创建一个具有特定原型的对象。const parentObj = { parentProp: 'I am parent' }; const childObj = Object.create(parentObj); console.log(childObj.parentProp); // "I am parent"
理解这些概念是深入掌握JavaScript的基础。变量提升、事件机制、作用域和原型链共同构成了JavaScript的核心特性,影响着代码的组织和执行方式。通过深入学习这些概念,开发者可以编写出更加高效、可维护的代码。
在为你的网页增加动态效果和扩充内容时,我们将使用现代JavaScript特性,比如ES6+语法、事件监听和一些简单的动态效果。这里是优化后的HTML和JavaScript代码:
我的个人主页完整源代码
HTML
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的个人主页</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<!-- Navbar -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="#">个人主页</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ml-auto">
<li class="nav-item active"><a class="nav-link" href="#">首页</a></li>
<li class="nav-item"><a class="nav-link" href="#bio">关于我</a></li>
<li class="nav-item"><a class="nav-link" href="#hobbies">兴趣</a></li>
<li class="nav-item"><a class="nav-link" href="#contact">联系</a></li>
</ul>
</div>
</nav>
<!-- Header -->
<header class="header bg-dark text-white text-center py-5">
<h1>欢迎来到我的个人主页</h1>
<p>探索我最新的项目和学习旅程</p>
</header>
<!-- Main Content -->
<main class="content container mt-4">
<div class="row">
<!-- Bio Section -->
<section id="bio" class="col-lg-4 col-md-6 mb-4">
<div class="card shadow-sm">
<img src="https://wxdwuxd.oss-cn-beijing.aliyuncs.com/4027b724a62b206a73ba495e732af2b.jpg" class="card-img-top" alt="Profile Image">
<div class="card-body">
<h2 class="card-title">关于我</h2>
<p class="card-text">你好!我是一个前端开发的初学者,正在学习如何创建美观且有用的网页。</p>
</div>
</div>
</section>
<!-- Hobbies Section -->
<section id="hobbies" class="col-lg-4 col-md-6 mb-4">
<div class="card shadow-sm">
<div class="card-body">
<h2 class="card-title">爱好与兴趣</h2>
<ul class="list-group list-group-flush">
<li class="list-group-item">编程</li>
<li class="list-group-item">阅读</li>
<li class="list-group-item">旅行</li>
</ul>
</div>
</div>
</section>
<!-- Projects Section -->
<section class="col-lg-4 col-md-6 mb-4">
<div class="card shadow-sm">
<div class="card-body">
<h2 class="card-title">查看我的作品</h2>
<ul class="list-group list-group-flush">
<li class="list-group-item"><a href="#">我的第一个项目</a></li>
<li class="list-group-item"><a href="#">一个有趣的项目</a></li>
</ul>
</div>
</div>
</section>
<!-- Skills Section -->
<section id="skills" class="col-lg-12 mb-4">
<div class="card shadow-sm">
<div class="card-body">
<h2 class="card-title">技能</h2>
<p class="card-text">HTML, CSS, JavaScript, 和 Bootstrap</p>
<div class="progress">
<div class="progress-bar bg-success" role="progressbar" style="width: 70%" aria-valuenow="70" aria-valuemin="0" aria-valuemax="100">HTML 70%</div>
</div>
<div class="progress mt-2">
<div class="progress-bar bg-info" role="progressbar" style="width: 60%" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100">CSS 60%</div>
</div>
<div class="progress mt-2">
<div class="progress-bar bg-warning" role="progressbar" style="width: 50%" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100">JavaScript 50%</div>
</div>
</div>
</div>
</section>
</div>
<!-- Contact Form Section -->
<section id="contact" class="py-4 bg-light rounded shadow-sm">
<h2 class="text-center">联系我</h2>
<form class="px-4" id="contactForm">
<div class="form-row">
<div class="form-group col-md-6">
<label for="name">姓名</label>
<input type="text" class="form-control" id="name" placeholder="输入姓名">
</div>
<div class="form-group col-md-6">
<label for="email">邮箱</label>
<input type="email" class="form-control" id="email" placeholder="输入邮箱">
</div>
</div>
<div class="form-group">
<label for="message">留言</label>
<textarea class="form-control" id="message" rows="4" placeholder="输入留言"></textarea>
</div>
<button type="submit" class="btn btn-primary">发送</button>
</form>
</section>
</main>
<!-- Footer -->
<footer class="footer bg-dark text-white text-center py-2">
<p>联系我:<a class="text-white" href="https://blog.csdn.net/wxdzuishaui?spm=1010.2135.3001.5343">我的博客</a></p>
</footer>
<!-- JavaScript -->
<script>
document.getElementById('contactForm').addEventListener('submit', function(event) {
event.preventDefault();
alert('表单已提交,谢谢您的留言!');
});
const cards = document.querySelectorAll('.card');
cards.forEach(card => {
card.addEventListener('mouseover', () => {
card.style.boxShadow = '0 8px 16px rgba(0, 0, 0, 0.2)';
});
card.addEventListener('mouseout', () => {
card.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.1)';
});
});
</script>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
CSS
和昨天的个人主页一致
添加的功能与样式
-
动态效果:
- 卡片悬停效果:当悬停在卡片上时,它们会有更深的阴影和缩放效果。
- 表单提交模拟:拦截表单提交事件并显示一条感谢信息。
-
界面扩展:
- 添加了“技能”部分,可以用进度条呈现技能水平。
- 更详细的头部欢迎信息和排版优化。
-
脚本:
- 使用了
addEventListener
为卡片和表单添加动态行为。
- 使用了
这些改进对网站的样式和交互性会有很好的提升,并且展示了使用JavaScript进行页面动态效果的基本方法。
(明天将会教学如何用github的静态网址来布置个人界面)