学习笔记,在上网课的时候随手写的,可能不准确,还请见谅。抱拳!
JavaWeb:用 Java 语言开发动态 Web 服务的一套技术体系(后端)。 HTML/CSS/JS 属于前端;JavaWeb 是服务端,接收浏览器发来的 HTTP 请求,处理业务、操作数据库,返回页面或者 JSON 数据。
通信流程:浏览器(客户端) → HTTP 请求 → Tomcat 服务器 → Servlet 处理 → JDBC 操作 MySQL → 组装数据(页面 / JSON)→ HTTP 响应 → 浏览器渲染页面。
Web标准也称为网页标准,有一系列的标准组成,大部分有W3c负责制定。三个组成部分:HTML:负责网页的结构。CSS:负责网页的表现(页面元素的外观,位置等页面样式,如:颜色,大小等)。JavaScript:负责网页的行为。
HTML+CSS回顾
简介
HTML(HyperText Markup Language):超文本标记语言,用来搭建网页结构,不是编程语言(没有逻辑、没有运算),是标记语言。超文本:不只是纯文字,可以包含图片、音频、视频、链接,点击链接可以跳转到别的页面。标记:用一对一对的标签包裹内容,浏览器识别标签然后渲染展示。后缀名:.html / .htm,直接用浏览器打开就能看。
CSS(Cascading Style Sheets):层叠样式表,作用是给 HTML 页面美化样式。一句话区分:HTML 搭骨架(有什么内容),CSS 负责外观(长什么样),JavaScript 负责动作交互。层叠:多个样式规则叠加在一起,有优先级规则,冲突时按规则覆盖。样式表:专门存放颜色、大小、布局、字体、间距等样式代码,不是编程语言,没有变量逻辑(CSS3 之后有变量,但本质还是样式描述语言)。
标签
标题标签
一共 6 级标题,块级元素,独占一行,自带默认加粗、上下间距。 <h1>:一级标题(最重要,一个页面建议只用 1 个)。 <h2>:二级标题。 <h3>:三级标题。 <h4>:四级标题。 <h5>:五级标题。 <h6>:六级标题(字号最小)。
//示例代码
<h1>一级标题</h1>
<h2>二级标题</h2>
<h3>三级标题</h3>
<h4>四级标题</h4>
<h5>五级标题</h5>
<h6>六级标题</h6>
超链接标签 <a>
行内元素,作用:跳转页面、跳转锚点、打电话、发邮件等。
核心属性:href✅ 必须写,跳转地址。外部网址href="https://www.baidu.com";本地页面:`href="index.html";空链接:href="#"(点击回到顶部)。 target控制在哪打开页面_self:默认,当前窗口打开;_blank:新标签页打开(最常用)。
<!– 外部链接,新窗口打开 –>
<a href="https://www.baidu.com" target="_blank">百度</a>
<!– 本地页面链接 –>
<a href="about.html">关于我们</a>
<!– 空链接 –>
<a href="#">空链接</a>
段落标签 <p>
块级元素,用来表示一段文字,自带上下默认间距。
示例代码:
<p>这是第一段文字。HTML用来搭建网页结构。</p>
<p>这是第二段文字。CSS用来设置样式。</p>
<p>里面不能放块级标签(h、div、p 等)。多个回车、空格在页面只会显示成一个空格;换行要用 <br>(换行标签,空标签)。
图片标签
空标签,没有结束标签,行内块元素。
示例代码:
<img src="dog.jpg" alt="小狗图片" title="可爱小狗" width="300">
src:✅ 必须,图片路径(本地图片 / 网络图片地址)。alt:图片加载失败时显示的文字(给搜索引擎、无障碍阅读用,建议必写)。title:鼠标放到图片上弹出的文字提示。width / height:宽高,只写一个,图片会等比例缩放。
路径两种:相对路径:img/1.jpg(项目内文件,开发最常用);绝对路径:网络完整地址 2026-10-26g1mial0rktf.jpg。
视频标签 <video>
HTML5 新增,播放视频,不需要插件。
示例代码:
<video src="视频地址" controls width="500">
您的浏览器不支持video标签
</video>
src:视频路径。controls:显示播放控件(播放、暂停、进度条、音量,一定要加)。autoplay:自动播放(很多浏览器要求搭配 muted静音才能自动播)。muted:静音。loop:循环播放。poster:视频没播放时显示的封面图。
Strong 标签
示例代码:
<strong>加粗文字</strong>
<b>加粗文字</b>
区别:<strong> 有强调语义;<b> 只是视觉加粗,无语义。
表单标签
作用:收集用户信息,提交给后端服务器。所有表单控件一般都放在 <form></form>里面。
action:提交地址(数据发给谁)。 method:提交方式,常用 get / post。 get:参数拼在网址后面,不安全,适合少量数据。 post:放在请求体里,适合密码、长数据。
示例代码:
<form action="xxx.php" method="post">
<!– 表单控件放这里 –>
</form>
input 输入框
//type属性决定是什么控件
<!– 文本输入框 –>
<input type="text" placeholder="请输入用户名">
<!– 密码框,内容隐藏 –>
<input type="password" placeholder="请输入密码">
<!– 单选框 radio,name必须相同才能互斥 –>
<input type="radio" name="sex" id="man"> <label for="man">男</label>
<input type="radio" name="sex" id="woman"> <label for="woman">女</label>
<!– 复选框 checkbox –>
<input type="checkbox" name="hobby" id="game"> <label for="game">游戏</label>
<input type="checkbox" name="hobby" id="read"> <label for="read">阅读</label>
<!– 提交按钮 –>
<input type="submit" value="提交">
<!– 重置按钮,一键清空表单 –>
<input type="reset" value="重置">
<!– 普通按钮,配合js使用 –>
<input type="button" value="普通按钮">
placeholder:提示文字,不是输入的值。 checked:默认选中(radio、checkbox)。 name:提交时参数名,提交表单必须写 name。 label:点击文字也能选中框,for 和 input 的 id 对应。
下拉选择框 <select> + <option>
<select name="city">
<option value="zz">郑州</option>
<option value="jz" selected>焦作</option>
<option value="bj">北京</option>
</select>
selected:默认选中这一项。
文本域 <textarea>
适合留言、简介。rows:行数,cols:宽度;可以用 css 控制大小。
<textarea name="msg" rows="4" cols="30" placeholder="请输入留言"></textarea>
button 按钮标签
示例代码:
<button type="submit">提交表单</button>
<button type="reset">重置</button>
<button type="button">普通按钮</button>
表单分组 fieldset + legend
给表单加边框分组。示例代码:
<fieldset>
<legend>用户信息</legend>
<input type="text">
</fieldset>
CSS 引入方式
行内样式(内联样式)
写在标签的 style 属性里,优先级最高:
//语法
<标签 style="属性:值; 属性:值;">内容</标签>
//示例代码
<h2 style="color:red; font-size:24px;">红色标题</h2>
内部样式表(内嵌样式)
在 <head> 里面写 <style>标签,CSS 代码写在里面。
示例代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>内部样式</title>
<style>
h2 {
color: green;
font-size: 22px;
}
</style>
</head>
<body>
<h2>绿色标题</h2>
</body>
</html>
外部样式表(外链式,开发最常用)
CSS 单独保存为 .css文件,通过 <link> 标签引入。
<link rel="stylesheet" href="style.css">
选择器
作用:选中 HTML 元素,给它设置样式。
标签选择器
直接写标签名,选中页面所有该标签。
p {
color: red;
}
类选择器(最常用)
符号:.,HTML 用 class调用。特点:一个类可以给多个标签;一个标签可以加多个类 class="box text"。语法:
.box {
font-size: 18px;
}
id 选择器
符号:#,HTML 用 id调用。
示例代码:
#nav {
background: #ccc;
}
通配符选择器 *
选中页面所有标签。常用于初始化样式,清除默认内外边距。
示例代码:
* {
margin: 0;
padding: 0;
}
文本修饰
行高 line-height
作用:控制一行文字的高度,可以实现文字垂直居中。
示例代码:
p {
line-height: 26px; /* 固定像素 */
line-height: 1.5; /* 无单位:当前字体大小的1.5倍(最推荐) */
}
首行缩进 text-indent
段落开头空两格!2em:代表2 个汉字宽度,适配不同字号,首选!不要直接写 px,字号一变空格就乱了。
示例代码:
p {
text-indent: 2em;
}
盒子模型
网页中所有元素都可以看成一个盒子,由 内容 (content)、内边距 (padding)、边框 (border)、外边距 (margin) 四部分组成。 标准盒子:元素实际宽度 = width + padding + border + margin,margin 是盒子外面的距离,不会撑大盒子本身,只是推开别的盒子。
padding 内边距(内容和边框之间的距离)
会撑大盒子,写法(顺时针:上、右、下、左)。示例代码:padding不能写负数。
.box {
/* 四个方向一样 */
padding: 10px;
/* 上下10px,左右20px */
padding: 10px 20px;
/* 上10 左右20 下30 */
padding: 10px 20px 30px;
/* 上、右、下、左 */
padding: 10px 20px 30px 40px;
/* 单独设置某一边 */
padding-top: 5px;
padding-right: 5px;
padding-bottom: 5px;
padding-left: 5px;
}
margin 外边距(盒子和其他盒子之间的距离)
不会撑大盒子。示例代码:
.box {
margin: 10px;
margin: 10px 20px;
margin: 10px 20px 30px;
margin: 10px 20px 30px 40px;
margin-top: 10px;
margin-left: 10px;
}
//经典用法,水平居中
margin: 0 auto;
注意坑:垂直 margin 塌陷(合并):两个块级元素上下 margin 会合并,取最大值,不是相加。
border 边框
.box {
/* 宽度 样式 颜色 */
border: 1px solid #000;
/* 单边边框 */
border-top: 2px dashed red;
}
样式:solid实线、dashed虚线、dotted点线。
box-sizing 盒模型
content-box
默认,标准盒模型。width 只代表内容宽度。盒子实际宽 = width + padding + border。
box-sizing: content-box;
border-box(推荐!IE 盒模型)
width是盒子总宽度,padding、border 往内部挤内容,不会撑大盒子。实际内容宽度 = width – padding – border。
box-sizing: border-box;
flex布局
作用:给父盒子开启 flex,用来控制子元素的排列、对齐,非常适合一维布局(横向 / 纵向)记住:给父元素加 display:flex,子元素自动变成弹性项目。
父容器属性
.father {
display: flex; /* 开启flex布局 */
}
flex-direction:主轴方向(子元素排列方向) row默认:主轴水平,从左到右(横向排)。 row-reverse:水平,从右往左。 column:主轴垂直,从上到下(纵向排)。 column-reverse:垂直,从下往上。
justify-content:主轴上的对齐方式
主轴就是 flex-direction 设置的那条轴 flex-start默认:靠主轴起点。 flex-end:靠主轴终点。 center:居中(最常用)。 space-between:两边贴边,中间均分空隙。 space-around:每个元素左右都有均等空隙。 space-evenly:所有空隙完全相等。
align-items:侧轴(交叉轴)对齐
侧轴和主轴垂直 主轴横向 (row) 时,侧轴就是垂直方向 stretch默认:子元素拉伸填满父高度(子不设高度才生效)。 flex-start:侧轴起点。 flex-end:侧轴终点。 center:垂直居中(超级常用!)。
示例代码:
flex-direction: row;
justify-content: center;
align-items: center;
这里仅是回顾的一部分,只是冰山一角,若想了解更多请参考:
(作者笔记)前篇:HTML5与CSS3
(作者笔记)后篇:css与移动Web
官方文档:MDN Web Docs
JavaScript
JavaScript是一门弱类型、解释型、面向对象**的脚本语言,和 HTML、CSS 并称前端三大基石。和 Java 没有关系,只是名字相似。
JS 分为:ECMAScript + DOM + BOM 1. ECMAScript(ES 核心语法)。规定 JS 的基础语法,是 JS 的标准核心。包含:变量、数据类型;运算符、分支、循环;函数、数组、对象;内置对象(Math、Date 等)。作用:语言本身的逻辑能力,和浏览器无关。
2. DOM(Document Object Model 文档对象模型)。文档对象模型,用来操作页面标签(HTML),包含:获取元素、修改内容、修改样式;增删元素、绑定事件。作用:操作网页结构。 3. BOM(Browser Object Model 浏览器对象模型)浏览器对象模型,用来操作浏览器窗口。包含: window(BOM 顶级对象) alert / prompt / confirm location 地址栏 history 前进后退 navigator 浏览器信
核心语法
三种引入方式
行内 JS:缺点:结构、样式、逻辑混在一起,维护麻烦。
示例代码:
<!– 点击弹窗 –>
<button onclick="alert('行内JS')">点我</button>
<!– a标签 –>
<a href="javascript:alert('a标签行内js')">测试</a>
内部 JS : 放置位置建议:放在 </body>前面即底部:页面元素先加载,JS 才能正常获取标签。如果放在 head 里,一般要加 window.onload等页面加载完毕再执行。
示例代码:
<script>
console.log('内部JS代码');
</script>
外部 JS(项目最推荐,单独 .js 文件)
新建文件 test.js,之后再引入。
console.log("外部js文件内容");
<script src="test.js"></script>
注意:script 标签一旦加了 src,标签中间写的代码不会执行。如:
<!– 错误,里面代码无效 –>
<script src="test.js">
alert("这段不执行!")
</script>
变量
变量:可以变化的数据,用来存东西。 let:现代推荐,块级作用域,不允许重复声明。 var:旧写法,函数作用域,有变量提升,容易出 bug,尽量不用。
示例代码:
// 声明 + 赋值
let name = "张三";
let age = 18;
// 可以修改
age = 19;
// 先声明,后赋值
let sex;
sex = "男";
常量
常量:值不允许修改,一旦赋值不能重新赋值。注意:const 如果存数组 / 对象,里面内容可以改,只是不能换地址。
示例代码:
const PI = 3.1415926;
// PI = 3.15; // 报错!不能修改
const arr = [1,2,3];
arr.push(4); // ✅ 合法,数组本身引用没变
数据类型
简单数据类型
//string 字符串:引号包裹(单 / 双 / 反引号`\\``)
let s1 = 'hi';
let s2 = "hello";
let s3 = `模板字符串,可以换行${s1}`;
//number 数字:整数、小数、NaN、Infinity
let num1 = 10;
let num2 = 3.14;
let n = NaN; // 不是一个数字
//boolean 布尔:只有两个值 true / false
let flag = true;
//undefined:变量声明了,但没有赋值
let a;
console.log(a); // undefined
//null:空值,代表手动设置为空
let b = null;
//小考点:typeof null 结果是 object,历史 bug
引用数据类型(存地址,堆内存)
//object 对象
let obj = {name:"小明",age:20};
//array 数组(属于对象)
let arr = [10,20,30];
//function 函数(也是对象)
//typeof 检测数据类型
typeof 'abc' // 'string'
typeof 123 // 'number'
typeof true // 'boolean'
typeof undefined // 'undefined'
typeof null // 'object'
typeof [] // 'object'
typeof {} // 'object'
typeof function(){} // 'function'
函数
函数就是一段可以重复调用、封装好的代码块,用来实现某个功能,减少重复代码。
函数声明
特点:函数提升,可以先调用,后写函数。
示例代码:
// 语法
function 函数名(参数1,参数2){
// 函数体:要执行的代码
return 返回值; // return 把结果抛出去,结束函数
}
// 示例
function add(a,b){
let sum = a + b;
return sum;
}
// 调用
let res = add(10,20);
console.log(res); // 30
函数表达式(匿名函数)
把函数赋值给变量,没有函数提升,必须先定义再调用。
示例代码:
let fn = function(){
console.log("函数表达式");
}
fn();
箭头函数(ES6,简写,非常常用)
箭头函数没有自己的 this,不适合做事件处理、对象方法。
示例代码:
// 标准写法
let fn1 = () => {
console.log("箭头函数");
}
fn1();
// 只有一个参数,可以省略括号
let fn2 = x => x * 2;
console.log(fn2(5)); //10
// 只有一行return,省略 {} 和 return
let add2 = (a,b) => a + b;
console.log(add2(2,3)); //5
自定义对象
对象(Object)用来保存一组相关的属性和方法,是键值对的集合。属性:描述对象的特征(名词,比如名字、年龄)。方法:对象的行为(动词,比如说话、跑步,本质是函数)。
字面量创建
示例代码:
// {} 包裹,键:值,多个用逗号隔开
let person = {
name: "小明",
age: 18,
gender: "男",
// 方法
sayHi: function () {
console.log("你好,我是" + this.name);
}
};
访问属性 / 调用方法
// 点语法(推荐)
console.log(person.name);
person.sayHi();
// 中括号语法,适合变量名、特殊名字
console.log(person["age"]);
修改、新增、删除属性
person.age = 19; // 修改
person.hobby = "打球"; // 新增
delete person.gender; // 删除属性
new Object () 创建
let student = new Object();
student.name = "小红";
student.age = 20;
student.study = function () {
console.log("我在学习");
};
student.study();
构造函数(批量创建多个相似对象)
字面量适合单个对象;如果要造一堆结构一样的对象,用构造函数。
示例代码:
// 约定:构造函数首字母大写
function People(name, age) {
this.name = name;
this.age = age;
this.say = function () {
console.log(this.name + ":" + this.age);
};
}
// new 实例化对象
let p1 = new People("张三", 22);
let p2 = new People("李四", 21);
p1.say();
p2.say();
注:自定义对象里,不推荐把箭头函数当作对象的方法。
错误示例:
let person = {
name: "小明",
sayHi: () => {
console.log(this.name);
}
}
person.sayHi();
// this 不是 person!
// 浏览器环境 this → window,拿不到 name
JSON
JSON 全称:JavaScript Object Notation(JS 对象表示法)。是一种轻量级的数据交换格式,前后端传数据最常用。
语法规则(严格!考点) 1. 键(属性名)必须用双引号 `"`,不能单引号、不能不写引号。 2. 值只能是这几种类型:字符串、数字、布尔、null、数组、对象。不能:函数、undefined、Date 3. 逗号不能多写(最后一项后面不要加逗号,部分老环境报错)。 4. 整体是一个字符串,外面一般用单引号 / 反引号包起来。
示例代码:
// 标准JSON(这是字符串内容)
{
"name": "小明",
"age": 18,
"gender": "男",
"hobby": ["看书", "打球"],
"isStudent": true,
"address": null
}
核心转换方法
JSON.stringify
(JS数据)→ JS 对象 / 数组 → JSON 字符串(发给后端)。示例代码:
let obj = { name:"小明", age:18 };
let jsonStr = JSON.stringify(obj);
console.log(jsonStr);
// 输出字符串:{"name":"小明","age":18}
JSON.parse
(JSON字符串) → JSON 字符串 → JS 对象 / 数组(后端拿到数据,转成 JS 对象使用)
示例代码:
let str = '{"name":"小明","age":18}';
let obj2 = JSON.parse(str);
console.log(obj2.name); // 小明
JSON 也可以是数组格式
示例代码:
let arrJson = '[{"id":1,"name":"张三"},{"id":2,"name":"李四"}]';
let arr = JSON.parse(arrJson);
console.log(arr[0].name);
DOM
Document Object Model。作用:JS 通过 DOM 来操作 HTML 页面(增、删、改、查元素、内容、属性、样式、事件)。 DOM 是浏览器提供的 API,不属于 ECMAScript 语法。
DOM 树:浏览器把 HTML 文档解析成一棵节点树。document:整个文档,DOM 的顶级对;元素节点:html、head、body、div、p、img 等标签(最常用);文本节点:标签里面的文字;属性节点:标签上的属性(src、class、id);注释节点:html 注释。
获取元素
//推荐querySelector /querySelectorAll
// 获取匹配到的第一个元素
let one = document.querySelector(".box");
let btn = document.querySelector("#btn");
let p = document.querySelector("div > p");
// 获取全部,返回NodeList(可以用forEach)
let all = document.querySelectorAll("li");
//不常用
//通过 id 获取
// id唯一,返回一个元素
let box = document.getElementById("box");
//通过标签名获取 返回伪数组(HTMLCollection)
let lis = document.getElementsByTagName("li");
//通过类名获取
let items = document.getElementsByClassName("item");
操作元素内容
// innerText:只拿文本,忽略标签
box.innerText = "新文字";
// innerHTML:识别html标签
box.innerHTML = "<b>加粗文字</b>";
操作元素属性
示例代码:
//普通属性(src、href、title、id)
let img = document.querySelector("img");
img.src = "1.jpg"; // 修改
console.log(img.src); // 获取
//class 类名(控制 CSS 样式)
box.className = "red"; // 覆盖原来所有类
// classList(推荐,追加、删除、切换,不覆盖)
box.classList.add("active"); // 添加类
box.classList.remove("active"); // 删除类
box.classList.toggle("active"); // 有就删,没有就加
box.classList.contains("active");// 判断是否拥有这个类,返回布尔
事件监听
两种注册事件方式对比 传统方式:元素.onclick = function(){}。缺点:同一个事件只能绑定一个处理函数,后面的会覆盖前面的。 事件监听(推荐):addEventListener。优点:同一个事件可以绑定多个函数,互不覆盖。
onclick (传统事件绑定方式)
属于DOM 事件注册的老式写法,和 addEventListener事件监听是两套方案。
两种写法:写法①:行内写法(写在 HTML 标签上,不推荐大量使用)
<!– 直接写JS代码 –>
<button onclick="alert('你好')">点我</button>
<!– 调用函数 –>
<button onclick="sayHello()">点击</button>
<script>
function sayHello(){
console.log("hello");
}
</script>
缺点:结构和 JS 耦合在一起,不方便维护。
写法②:JS 中赋值(最常用的 onclick 写法)
<button id="btn">按钮</button>
<script>
let btn = document.querySelector('#btn');
// 给元素的onclick属性赋值一个函数
btn.onclick = function(){
console.log("按钮被点击");
}
</script>
优点:简单好写,适合简单 demo。 缺点:同一个元素同一个事件,只能绑定 1 个函数,后面会覆盖前面。
事件监听(推荐):addEventListener
优点:同一个事件可以绑定多个函数,互不覆盖
示例代码:
//语法
元素.addEventListener('事件名', 回调函数, 可选参数)
//代码
let btn = document.querySelector('button');
btn.addEventListener('click', function () {
console.log('点击1');
})
btn.addEventListener('click', function () {
console.log('点击2');
})
// 点击按钮,两条都会执行,不会覆盖
移除事件监听 removeEventListener
注意:匿名函数不能移除!必须使用命名函数。
function fn() {
console.log('点击');
}
btn.addEventListener('click', fn);
// 移除
btn.removeEventListener('click', fn);
第三个参数:捕获 / 冒泡(boolean)
- false(默认):冒泡阶段触发(从子 → 父)⭐最常用
- true:捕获阶段触发(从父 → 子)
事件冒泡
示例代码:
<div class="father">
<div class="son"></div>
</div>
let father = document.querySelector('.father')
let son = document.querySelector('.son')
father.addEventListener('click',()=>{console.log('父')})
son.addEventListener('click',()=>{console.log('子')})
// 点击son:先输出 子,再输出 父(冒泡)
阻止冒泡 e.stopPropagation()
son.addEventListener('click', function(e){
console.log('子')
e.stopPropagation() // 阻止事件向上冒泡,父不会触发
})
e:事件对象,形参随便起名,一般写 e /event
事件对象 event
回调函数第一个参数就是事件对象,保存本次事件所有信息。示例代码:
btn.addEventListener('click', function(e){
console.log(e);
e.target // 真正触发事件的元素(目标元素)
e.currentTarget // 绑定事件的元素
e.preventDefault() // 阻止默认行为(a跳转、表单提交)
})
阻止 a 标签默认跳转示例:
let a = document.querySelector('a')
a.addEventListener('click',function(e){
e.preventDefault()
})
事件委托
原理:利用事件冒泡,给父元素绑定事件,代理所有子元素。好处:1. 减少事件绑定,性能更好。2. 动态新增的子元素,自动拥有事件(传统 onclick 做不到)。
示例代码:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
let ul = document.querySelector('ul')
ul.addEventListener('click', function(e){
// 判断点击目标是不是li
if(e.target.tagName === 'LI'){
console.log('点击了li:', e.target.innerText)
}
})
// 后续JS新增的li,不用重新绑定事件!
常见事件
鼠标事件
| click | 鼠标单击 |
| dblclick | 鼠标双击 |
| mouseenter | 鼠标移入(不冒泡,推荐) |
| mouseleave | 鼠标移出(不冒泡,推荐) |
| mouseover | 鼠标移入(会冒泡) |
| mouseout | 鼠标移出(会冒泡) |
| mousedown | 鼠标按下 |
| mouseup | 鼠标松开 |
| mousemove | 鼠标移动 |
推荐优先 mouseenter / mouseleave,不容易因为子元素触发多次.
键盘事件(一般绑定 document /input)
| keydown | 按键按下(按住会连续触发) |
| keyup | 按键松开 |
| keypress | 按下字符键(已淘汰,不推荐) |
示例代码:
document.addEventListener('keydown', function(e){
console.log(e.key); // 获取按下的键
})
表单事件
| input | 输入内容改变,实时触发(最常用) |
| change | 内容失去焦点、确认修改后才触发 |
| focus | 获取焦点 |
| blur | 失去焦点 |
| submit | 表单提交(绑定 form,阻止提交 e.preventDefault ()) |
| reset | 表单重置 |
示例代码:
let ipt = document.querySelector('input')
ipt.addEventListener('input',()=>{console.log('实时输入')})
页面 / 窗口事件
| load | 页面、图片加载完成 |
| DOMContentLoaded | HTML 解析完成,不用等图片 css 加载完(更快) |
| resize | 窗口大小改变 |
| scroll | 页面滚动 |
window.addEventListener('scroll',()=>{})
VUE
官方文档 :Vue.js – 渐进式 JavaScript 框架 | Vue.js。
Vue(读音 /vjuː/,类似 view),是尤雨溪开发的渐进式前端 JS 框架,核心思想:数据驱动、组件化,基于 MVVM 模式,减少手动 DOM 操作Vue.js。
什么叫「渐进式」 不用一次性全套引入,可以按需使用:1. 简单页面:直接引入 Vue CDN,只用来做数据绑定。2. 复杂项目:搭配构建工具 Vite + VueRouter + Pinia,开发完整 SPA 单页应用。 ✅ MVVM 模型(重点) M Model:数据(后端返回、页面变量) V View:视图(HTML 模板) VM ViewModel:Vue 实例,中间桥梁 ViewModel 自动监听数据变化,自动更新页面;视图输入变化,同步回数据(双向绑定 v-model)。原生 JS:JS 手动操作 DOM。 Vue:数据 ↔ ViewModel ↔ 视图。
特性: 1. 响应式数据。数据一变,页面自动刷新;Vue3 底层用Proxy实现响应式(Vue2 用Object.defineProperty)。2. 组件化开发一个页面拆成很多独立、可复用组件(.vue单文件组件 SFC),每个组件包含 template、script、style,便于维护复用
- Vue2:已停止维护;选项式 API(Options API)
- Vue3:现在主流版本,性能更好、支持 TS;新增组合式 API(Composition API),<script setup>是现在最常用写法Vue.js
示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue-快速入门</title>
</head>
<body>
<div id="app">
<h1>{{message}}</h1>
<h1>{{count}}</h1>
</div>
<script type="module">
import { createApp, ref } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({
data(){
return {
message: 'hello Vue',
count: 100
}
}
}).mount('#app')
</script>
</body>
</html>
生命周期
生命周期:组件从创建 → 挂载 → 更新 → 销毁全过程,在特定时机自动执行的回调函数,叫生命周期钩子。四大阶段:创建、挂载、更新、销毁;setup最先执行,在 beforeCreate /created 之前。
| setup | 组件初始化,最早执行 | ❌ | 写响应式变量、函数、导入其他钩子,替代 beforeCreate、created |
| onBeforeMount | 挂载前,虚拟 DOM 准备好,还没生成真实 DOM | ❌ | 很少用 |
| onMounted | 挂载完成,DOM 已经渲染到页面 | ✅ | 最常用:axios 请求、获取 ref 元素、初始化图表、定时器 |
| onBeforeUpdate | 响应式数据变化,DOM 准备更新,旧 DOM 还在 | ✅ | 更新前记录旧位置、旧尺寸 |
| onUpdated | DOM 更新完成 | ✅ | 更新后操作新 DOM(谨慎,容易死循环) |
| onBeforeUnmount | 组件即将销毁,还能访问数据、DOM | ✅ | 重点:清除定时器、取消监听、终止 axios 请求、解绑事件 |
| onUnmounted | 组件已经销毁,DOM 移除 | ❌ | 收尾清理 |
Vue3 选项式 API
export default {
beforeCreate(){},
created(){},
beforeMount(){},
mounted(){},
beforeUpdate(){},
updated(){},
beforeUnmount(){}, // Vue2叫 beforeDestroy
unmounted() // Vue2叫 destroyed
}
常用指令
v-bind【属性绑定】
作用:给标签属性绑定动态数据。可以绑定:src、href、title、class、style
<template>
<!– 完整写法 –>
<img v-bind:src="imgUrl">
<!– ✅简写 : –>
<img :src="imgUrl">
<div :class="cls">测试</div>
</template>
<script setup>
import {ref} from 'vue'
const imgUrl = ref('logo.jpg')
const cls = ref('active')
</script>
v-on【事件绑定】
简写 @ ,作用:绑定点击、输入等事件,代替原生 addEventListener。常用事件:@click、@input、@mouseenter、@blur
示例代码:
<template>
<button v-on:click="fn">点我</button>
<!– ✅简写 @ –>
<button @click="fn">点我</button>
<!– 传参 –>
<button @click="add(10)">+10</button>
<!– 原生事件对象 $event –>
<button @click="getEvent($event)">获取事件对象</button>
</template>
<script setup>
const fn = ()=>{
alert('点击了')
}
const add = (n)=>{
console.log(n)
}
const getEvent = (e)=>{
console.log(e.target)
}
</script>
v-model 【双向数据绑定】
作用:数据 ↔ 表单输入框双向同步。本质语法糖:v-model = :modelValue + @update:modelValue。
示例代码:
<template>
<input v-model="msg" placeholder="请输入">
<p>你输入的:{{msg}}</p>
</template>
<script setup>
import {ref} from 'vue'
const msg = ref('')
</script>
v-if 条件渲染
作用:条件不成立,直接移除 DOM 元素。
<template>
<p v-if="flag">我是if</p>
<p v-else-if="flag2">else if</p>
<p v-else">否则</p>
</template>
<script setup>
import {ref} from 'vue'
const flag = ref(false)
const flag2 = ref(false)
</script>
v-show 显示隐藏
作用:条件不成立,只是加 display:none,DOM 还在页面里。
<template>
<p v-show="isShow">v-show</p>
</template>
<script setup>
import {ref} from 'vue'
const isShow = ref(true)
</script>
v-for 列表循环渲染
作用:遍历数组、对象,批量生成标签。必须加 :key,key 推荐用唯一 id,不要用 index(简单 demo 可以临时用 index)。
<template>
<!– (item, 索引) in 数组 –>
<li v-for="(item, index) in list" :key="item.id">
{{ index }} – {{ item.name }}
</li>
</template>
<script setup>
import {ref} from 'vue'
const list = ref([
{id:1, name:'张三'},
{id:2, name:'李四'}
])
</script>
Ajax
推荐教程:AJAX 简介 | 菜鸟教程
Axios官方文档:Axios中文文档 | Axios中文网
Ajax = Asynchronous JavaScript And XML,异步 JS 和 XML。作用:在不刷新整个页面的情况下,向服务器发送请求、获取数据,局部更新页面(前端非常核心的技术)。
特点 1. 异步:发请求的时候页面不会卡死,后台等待服务器返回,拿到数据再执行回调。 2. 局部刷新:不用刷新整个网页。 3. 早期用 XML 传数据,现在基本都用 JSON。
原生 JS AJAX
// 1. 创建请求对象
const xhr = new XMLHttpRequest()
// 2. 配置请求:请求方式,接口地址,是否异步true
xhr.open('GET', 'https://xxx/api/list', true)
// 3. 监听状态变化(服务器返回结果)
xhr.onreadystatechange = function () {
// readyState=4 请求完成;status=200 成功
if (xhr.readyState === 4 && xhr.status === 200) {
// 拿到后端返回的json字符串,转成js对象
const res = JSON.parse(xhr.responseText)
console.log(res)
}
}
// 4. 发送请求
xhr.send()
readyState 状态说明:0:未初始化。1:已经调用 open ()。2:已经调用 send (),响应头已接收 3:正在接收响应体。4:请求全部完成。
POST 请求写法
const xhr = new XMLHttpRequest()
xhr.open('POST', 'https://xxx/api/login', true)
// post必须设置请求头
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
xhr.onreadystatechange = function(){
if(xhr.readyState===4 && xhr.status===200){
console.log(JSON.parse(xhr.responseText))
}
}
// 携带参数
xhr.send('username=admin&password=123456')
Axios
Axios 是基于 Promise 的 HTTP 请求库,对原生 XMLHttpRequest 封装,Vue/React 项目最常用,浏览器、Node.js 都能用。优点:支持拦截器、自动转换 JSON、超时取消请求、防止 XSRF。
CDN 方式(直接 html 用)
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
GET:参数写在 params(拼在 url 后面)
// 写法1
axios.get('/api/user', {
params: { id: 1 }
}).then(res=>{
console.log(res.data) // 后端真实数据
}).catch(err=>{
console.log('请求失败',err)
})
// 写法2 async await(推荐,代码更顺)
async function getInfo(){
try{
const res = await axios.get('/api/user', {params:{id:1}})
console.log(res.data)
}catch(e){
console.log(e)
}
}
POST(json 格式,最常用),参数写在 data(请求体 json)
axios.post('/api/login',{
username:'admin',
password:'123456'
}).then(res=>{
console.log(res.data)
})
通用写法(axios ({config}))
axios({
method: 'POST',
url: '/api/login',
data: { username:'admin',pwd:'123' },
timeout: 5000
})
Maven
官方文档:Welcome to Apache Maven – Maven
Apache Maven,Java 生态最主流的项目构建 + 依赖管理工具,核心是用 pom.xml(POM,Project Object Model,项目对象模型)统一管理项目,替代手动导入 jar 包、手写编译打包脚本。
两大核心能力 1. 依赖管理:自动管理 jar 包,自动下载、自动传递依赖、解决版本冲突,只需要写坐标。 2. 项目构建:一套命令完成:清理 → 编译 → 单元测试 → 打包 → 安装 → 部署。
坐标
示例代码:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.15</version>
</dependency>
groupId:组织 / 公司包名(反向域名)。 artifactId:模块名。 version:版本号(SNAPSHOT快照版,不稳定;正式版无 SNAPSHOT)。。 packaging:打包类型,默认 jar,web 项目 war,父工程 pom。
仓库(找依赖的顺序)
本地仓库 → 私服(Nexus) → 中央仓库 本地仓库:本机缓存目录,默认 ~/.m2/repository,在 settings.xml 修改。 中央仓库:Maven 官方,国外慢,一般配阿里云镜像加速。 私服:企业内网私有仓库,存放内部 jar、私有构件。
idea 集成 Maven
IDEA 集成 Maven(两种方式:自带 Maven / 自己下载的 Maven,推荐后者)。快捷键:Ctrl+Alt+S 打开 Settings;重点:一定要配置【新项目设置】,不然新建项目每次恢复默认。
只改当前项目的 Settings,新建项目会变回自带 Maven!全局配置:1. 关闭当前所有项目,回到 IDEA 欢迎页。2. Customize → All settings(新版 IDEA)。 三个核心选项: 1. Maven home path:Maven 根目录。Bundled (Maven3):IDEA 自带,简单但版本固定、不方便自定义 settings,自己解压的 Maven:选解压根目录(如 D:\\apache-maven-3.8.8)。 2. User settings file:settings.xml,勾选 Override才能自定义。 3.Local repository:本地仓库目录,勾选 Override,改到非 C 盘路径。 ✅ 面试 / 开发标准配置:使用独立安装的 Maven + 自己的 settings.xml + 阿里云镜像。
IDEA 里执行 Maven 命令 两种方式: 1. 右侧 Maven 面板,双击生命周期阶段(clean/package/install)。 2. Terminal 终端直接敲 mvn clean package(前提:系统配置 maven 环境变量)。
Maven 依赖配置(pom.xml)
核心标签:<dependencies>,每一个 <dependency> 就是一个依赖。
示例:
<dependencies>
<dependency>
<!– 组织/公司,反向域名 –>
<groupId>junit</groupId>
<!– 模块名 –>
<artifactId>junit</artifactId>
<!– 版本 –>
<version>4.13.2</version>
<!– 依赖范围,可选 –>
<scope>test</scope>
<!– 排除传递依赖,可选 –>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
scope 依赖范围,控制依赖什么时候生效、会不会打进包。
| compile(默认) | 编译、测试、运行 | ✅ 打包 | spring、mybatis 业务核心包 |
| test | 仅测试 | ❌ 不打包 | JUnit |
| provided | 编译、测试;运行时容器提供 | ❌ 不打包 | servlet-api、tomcat 自带包 |
| runtime | 测试、运行;编译不需要 | ✅ 打包 | mysql 驱动 |
| system | 本地本机 jar,不推荐 | – | 极少使用 |
传递依赖 & 依赖排除
Maven 自动拉取依赖的依赖(传递依赖),容易出现版本冲突。 <exclusions>:排除某个传递依赖,不需要写 version。
依赖可选 optional,optional=true:本项目用这个依赖,不会传递给依赖我的项目。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.16</version>
<optional>true</optional>
</dependency>
Maven 生命周期
Maven 有三套互相独立的生命周期,生命周期由阶段(phase)组成;核心规则:执行某个阶段,会自动顺序执行它前面所有阶段;生命周期只是抽象流程,真正干活的是插件目标(goal)绑定到阶段。
1.clean 生命周期(清理)
作用:清理项目,删除 target 阶段顺序: 1. pre-clean :清理前准备 2. clean :删除 target 目录(核心) 3. post-clean :清理后收尾 命令:mvn clean→ 执行 pre-clean → clean
2.default 生命周期(核心构建,最重要)
用来编译、测试、打包、安装、部署,按顺序: 1. validate 校验项目、pom 信息是否合法 2. initialize 初始化 3. generate-sources 生成源码 4. process-sources 处理源码(过滤资源) 5. generate-resources 生成资源文件 6. process-resources 复制资源文件到 target/classes 7. compile ✅ 编译 java 源码,生成 class 文件 8. process-classes 处理编译后的 class 9. generate-test-sources 生成测试源码 10. process-test-sources 处理测试源码 11. generate-test-resources 生成测试资源 12. process-test-resources 复制测试资源 13. test-compile 编译测试代码 14. test ✅ 执行单元测试(JUnit) 15. prepare-package 打包前置准备 16. package ✅ 打包(jar/war)输出到 target 17. pre-integration-test 集成测试前准备 18. integration-test 运行集成测试 19. post-integration-test 集成测试后清理 20. verify 校验包是否合法、测试是否通过 21. install ✅ 安装到本地仓库,供本机其他项目依赖 22. deploy ✅ 上传到私服(Nexus),团队共享 常用命令对应: mvn compile 执行到 compile mvn test执行到 test mvn package 执行到 package mvn install 执行到 install mvn deploy 执行到 deploy
3.site 生命周期(了解即可)
生成项目文档、报表站点,开发很少用 1. pre-site 2. site生成 html 文档 3. post-site 4. site-deploy 把站点部署到服务器 命令:mvn site。
阶段、插件、目标关系
生命周期阶段本身没有功能;插件目标绑定到阶段,才会执行逻辑。 示例:maven-compiler-plugin 的 compile 目标 → 绑定 compile 阶段,负责编译。maven-surefire-plugin 的 test 目标 → 绑定 test 阶段,跑单元测试。maven-jar-plugin 的 jar 目标 → 绑定 package 阶段,打成 jar 包。
测试
单元测试(Unit Testing) 对象:最小单元(函数、方法、类)。执行者:开发人员。重点:单个逻辑是否正确,**隔离外部依赖,常用 Mock。例子:测试一个加法函数、工具类方法。
集成测试(Integration Testing) 对象:多个单元 / 模块组合后的接口、模块间交互。执行者:开发 / 测试。重点:模块之间传参、调用、数据交互是否正常。例子:Service 层调用 Dao、前端和后端接口联调。
系统测试(System Testing) 对象:完整的整个软件系统。执行者:测试工程师。重点:整体功能、性能、兼容性、界面,对照需求文档。例子:完整跑一遍业务流程、压力测试、多浏览器测试。
验收测试(Acceptance Testing) 对象:整套系统,面向用户需求。执行者:产品 / 客户 / 用户 α 测试:在开发环境,用户代表参与。β 测试:上线前,真实环境少量用户试用(公测) 重点:是否满足业务需求,能不能交付。补充:回归测试不属于独立阶段,是一种测试活动,每次改完代码,重新跑原有用例,防止旧功能坏掉。
测试方法
白盒测试
知道内部代码逻辑,按代码路径测。覆盖标准:语句覆盖、判定覆盖、条件覆盖、判定 – 条件覆盖、路径覆盖。常用技术:逻辑覆盖、基本路径测试。适用:单元测试为主。
黑盒测试(功能测试)
不看内部代码,只关心输入输出,基于需求 常用方法: 等价类划分:把输入分成有效、无效等价类,选代表用例。 边界值分析:测边界点(0、最大值、最小值),bug 最容易出在边界。 错误推测法:凭经验猜容易出错场景。 因果图:分析输入组合和输出的关系。 判定表:多条件组合场景。 场景法:按业务流程场景设计用例。
灰盒测试
介于黑白之间:知道简单接口、数据结构,不细看全部代码,多用于集成测试。
总结:单元测代码,集成测接口,系统测整体,验收测需求;白盒看代码,黑盒看功能。
单元测试
单元测试:对软件中最小可测试单元(一般是一个方法 / 类)独立进行测试,验证输入输出是否符合预期。执行者:开发人员。目的:尽早发现 bug,方便重构,回归验证。特点:独立、快速、可自动化执行。对比:普通 main 方法测试是手动;JUnit 是标准化自动化单元测试框架。
main 方法测试
在类里写 main 方法,手动调用待测试方法,打印结果,肉眼判断对错。 ✅ 优点:简单,不用导入框架 ❌ 缺点:1. 需要人工看输出,不能自动判断对错。2. 没有统一报告,不方便批量执行。3. 不能和构建工具(Maven/Gradle)集成。
示例代码:
public class Calculator {
public int add(int a, int b){
return a + b;
}
public static void main(String[] args) {
Calculator c = new Calculator();
int res = c.add(2,3);
System.out.println(res); // 自己看是不是5
}
}
JUnit 单元测试
JUnit 是 Java 最常用的单元测试框架,自动运行、自动判断结果、给出测试报告。 基本规范: 1. 测试类和被测试类分开(一般 XXXTest) 2. 测试方法无返回值、无参数、public 3. 用注解标记测试方法 4. 使用断言判断结果是否正确
示例代码:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CalculatorTest {
@Test
void testAdd(){
Calculator c = new Calculator();
int res = c.add(2,3);
assertEquals(5, res); // 断言:预期值5,实际结果res
}
}
断言
断言就是自动判断预期和实际是否一致,失败直接抛出异常,标记测试失败。需要静态导入:`import static org.junit.jupiter.api.Assertions.*;`
| assertEquals(预期,实际) | 值相等 |
| assertNotEquals(预期,实际) | 值不相等 |
| assertTrue(布尔表达式) | 结果为 true |
| assertFalse(布尔表达式) | 结果为 false |
| assertNull(对象) | 对象为 null |
| assertNotNull(对象) | 对象不为 null |
| assertAll(分组断言) | 多个断言一起执行,不会第一个失败就中断 |
| assertThrows(异常.class, 执行代码) | 预期抛出指定异常 |
JUnit5 常见注解
| @Test | 标记这是一个测试方法 |
| @BeforeEach | 每个测试方法执行前运行(初始化) |
| @AfterEach | 每个测试方法执行后运行(释放资源) |
| @BeforeAll | 所有测试方法执行前,只执行一次;方法必须 static |
| @AfterAll | 所有测试方法执行结束后,只执行一次;方法必须 static |
| @Disabled | 跳过该测试方法 / 类,不执行 |
| @DisplayName("测试名称") | 自定义测试显示名字,方便看报告 |
参数化测试
同一个测试逻辑,多组输入数据重复测试,不用写多个 @Test 方法。 依赖:需要额外引入参数化依赖包(junit-jupiter-params)。
核心注解: @ParameterizedTest:标记参数化测试 @ValueSource:简单单值数据源(int、String 等) @CsvSource:多参数,逗号分隔一组数据 @CsvFileSource:从外部 csv 文件读取数据
示例代码
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ParameterizedTest
@ValueSource(ints = {2,4,6,8})
void testEven(int num){
assertTrue(num % 2 == 0);
}


实现100%通过率-171主机测评](https://www.171host.com/wp-content/uploads/2026/10/20261026130223-6adf4f5f34184-220x80.gif)


