This commit is contained in:
rou
2026-03-23 14:56:04 +08:00
parent 00d3c9e4c6
commit 1071f4db05
27 changed files with 549 additions and 50 deletions

View File

@@ -5,6 +5,20 @@ const students = [
{ name: "小陈", finished: false },
];
const scores1 = scores.map(item => item = item + '分')
const scores2 = scores.filter(item => item > 60)
const scores3 = scores.reduce((acc, item) => { return item + acc }, 0)
const scores4 = scores.find(item => item >= 90)
const scores5 = scores.some(item => item >= 90)
const scores6 = students.every(item => item.finished === true)
console.log("分数:" + scores1);
console.log("及格分:" + scores2);
console.log("总分:" + scores3);
console.log("第一个 >= 90 的分数:" + scores4);
console.log("是否存在不及格:" + scores5);
console.log("是否都及格:" + scores6);
// 任务:
// 1. 用 map 生成 ["58分", ...]
// 2. 用 filter 筛出及格分
@@ -12,3 +26,9 @@ const students = [
// 4. 用 find 找到第一个 >= 90 的分数
// 5. 用 some 判断是否存在不及格
// 6. 用 every 判断 students 是否都 finished 为 true
/* 用 `map` 生成带单位的新数组
- 用 `filter` 找出及格成绩
- 用 `reduce` 计算总分
- 用 `find` 找出第一条大于等于 90 的成绩
- 用 `some` 判断是否有人不及格
- 用 `every` 判断是否全部完成考试*/

View File

@@ -19,7 +19,16 @@ function printStepTwo() {
function updateUser(user) {
// 任务:
// 1. 修改 user.city
user.city = '北京'
}
scoreB = 90
console.log('scoreA' + scoreA + ',scoreB' + scoreB);
userB.city = '秦皇岛'
console.log(userA.city, userB.city);
printStepOne()
printStepTwo()
updateUser(userA)
console.log(userA);
// 任务:
// 2. 修改 scoreB观察 scoreA 是否变化

View File

@@ -6,9 +6,43 @@ const finalComment = null;
let statusText = "";
const finishedRecords = [];
switch (learningStatus) {
case 'review':
console.log('已学习')
break
case 'ing':
console.log('学习中');
break
case 'prepare':
console.log('未学习');
break
default:
console.log('状态未知');
break
}
console.log(optionalNote, finalComment);
for (let i = 0; i < records.length; i++) {
if (records[i] === null || records[i] === undefined) {
console.log(`${i + 1}项为空值,停止读取`)
break
} else {
finishedRecords.push(records[i])
}
}
console.log(finishedRecords)
// 任务:
// 1. 用 switch 给 learningStatus 生成说明文字
// 2. 输出 optionalNote 和 finalComment 分别是什么
// 3. 用 for 循环读取 records
// 4. 如果遇到 undefined 或 null就 break
// 5. 输出 finishedRecords
/*用 `switch` 根据学习状态输出不同说明
- 观察 `undefined` 和 `null` 的区别
- 用循环读取学习记录
- 如果读到 `undefined` 或 `null`,立即用 `break` 停止循环
- 输出停止前已经读取到的内容*/

View File

@@ -2,6 +2,7 @@ const reviewer = {
name: "林晨",
stage: "final-review",
showTitle() {
console.log(`学习营总复盘器`);
// 输出总复盘标题
},
};
@@ -14,12 +15,47 @@ const lessons = [
{ title: "综合回顾", score: 95, finished: true },
];
let mentorNote;
const reviewComment = null;
let mentorNote;//undefined
const reviewComment = null;//null
function getStageText(stage) {
// 用 switch 返回阶段说明
switch (stage) {
case 'final-review':
console.log('已学习');
break
case 'ing-review':
console.log('学习中');
break
case 'start-review':
console.log('未学习');
break
default:
console.log('状态未知');
break
}
}
reviewer.showTitle()
console.log(mentorNote, reviewComment);
const lessons1 = []
for (let i = 0; i < lessons.length; i++) {
if (lessons[i].score != null) {
lessons1.push(lessons[i])
}
}
const sum = lessons.reduce((acc, item) => {
return acc + item.score
}, 0)
console.log("总分:" + sum);
console.log(`平均分:${sum / lessons.length}`);
const reviewerAlias = reviewer
reviewerAlias.stage = 'ing-review'
console.log(reviewer.stage, reviewerAlias.stage);
// 任务:
// 1. 调用 reviewer.showTitle()
@@ -28,3 +64,11 @@ function getStageText(stage) {
// 4. 用高阶函数统计课程标题、完成状态和平均分
// 5. 创建 reviewerAlias 指向 reviewer修改 stage观察原对象是否变化
// 6. 输出最终结果
/* 一个带方法的 `reviewer` 对象
- 一个 `lessons` 数组
- 一个用 `switch` 输出阶段说明的函数
- 一个用 `for + break` 清洗有效数据的过程
- 至少两个数组高阶函数
- 对 `undefined` 和 `null` 的判断
- 一段对象引用变化的观察代码
- 最终输出标题、有效课程、平均分、完成状态*/

View File

@@ -1,52 +1,59 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>获取元素</title>
<style>
body {
margin: 0;
padding: 32px;
font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
background: #f6f8fb;
}
.panel {
max-width: 760px;
margin: 0 auto;
padding: 24px;
border-radius: 20px;
background: #ffffff;
border: 1px solid #dbe3f0;
}
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>获取元素</title>
<style>
body {
margin: 0;
padding: 32px;
font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
background: #f6f8fb;
}
.cards {
display: grid;
gap: 12px;
margin-top: 18px;
}
.panel {
max-width: 760px;
margin: 0 auto;
padding: 24px;
border-radius: 20px;
background: #ffffff;
border: 1px solid #dbe3f0;
}
.card {
padding: 16px;
border-radius: 14px;
background: #f8fbff;
border: 1px solid #dce8f8;
}
</style>
</head>
<body>
<section class="panel">
<h1 id="page-title">DOM 获取元素练习</h1>
<button class="start-btn" type="button">开始学习</button>
.cards {
display: grid;
gap: 12px;
margin-top: 18px;
}
<div class="cards">
<article class="card">获取标题</article>
<article class="card">获取按钮</article>
<article class="card">获取一组卡片</article>
</div>
</section>
.card {
padding: 16px;
border-radius: 14px;
background: #f8fbff;
border: 1px solid #dce8f8;
}
</style>
</head>
<script src="./starter.js"></script>
</body>
</html>
<body>
<section class="panel">
<h1 id="page-title">
<p>111</p> 获取元素练习
</h1>
<button class="start-btn" type="button">开始学习</button>
<div class="cards">
<article class="card">获取标题</article>
<article class="card">获取按钮</article>
<article class="card">获取一组卡片</article>
</div>
</section>
<script src="./starter.js"></script>
</body>
</html>

View File

@@ -3,3 +3,11 @@
// 2. 用 querySelector 获取按钮
// 3. 用 querySelectorAll 获取全部卡片
// 4. 在控制台输出标题文字、按钮文字和卡片数量
const a = document.getElementById("page-title")
console.log(a.textContent);
const b = document.querySelector(".start-btn")
console.log(b.textContent);
const c = document.querySelectorAll(".card")
console.log(c.length);

View File

@@ -3,3 +3,9 @@
// 2. 修改标题文字
// 3. 给标签加上 done 类名
// 4. 修改描述文字颜色
const a = document.getElementById("title")
const b = document.getElementById("description")
const c = document.getElementById("badge")
a.textContent = "学习状态非常好"
a.classList.add("badge.done")
b.style.color = "red"

View File

@@ -1,4 +1,22 @@
// 任务:
// 1. 获取新增按钮、删除按钮和列表
// 2. 点击新增按钮时创建一个新的 li 并追加到列表
// 3. 点击删除按钮时删除最后一个 li
const add = document.getElementById("add-btn")
const remove = document.getElementById("remove-btn")
const list = document.getElementById("task-list")
add.onclick = function () {
const a = document.createElement("li")
a.textContent = "巧克力"
list.appendChild(a)
}
remove.onclick = function () {
const c = list.lastElementChild
if (c) {
c.remove()
}
}

View File

@@ -4,3 +4,26 @@ let count = 0;
// 1. 获取数字元素和 3 个按钮
// 2. 点击按钮时更新 count
// 3. 每次修改后,把最新 count 渲染到页面
const num = document.getElementById("value")
const del = document.getElementById("decrease-btn")
const add = document.getElementById("increase-btn")
const reset = document.getElementById("reset-btn")
function ren() {
num.textContent = count
}
add.addEventListener("click", function () {
count++
ren()
})
del.addEventListener("click", function () {
count--
ren()
})
reset.addEventListener("click", function () {
count = 0
ren()
})

View File

@@ -4,3 +4,17 @@
// 3. 用 preventDefault() 阻止默认提交
// 4. 读取输入框内容,创建新 li追加到列表
// 5. 清空输入框
const form = document.getElementById("todo-form")
const input = document.getElementById("todo-input")
const list = document.getElementById("todo-list")
form.addEventListener("submit", function (e) {
e.preventDefault()
const text = input.value.trim()
if (text) {
const li = document.createElement("li")
li.textContent = text
list.appendChild(li)
input.value = ""
}
})

View File

@@ -3,3 +3,28 @@
// 2. 给 lesson-list 绑定点击事件,使用事件委托
// 3. 点击 li 时切换 active 类名
// 4. 点击删除按钮时,阻止冒泡并删除当前 li
const panel = document.getElementById("panel")
panel.addEventListener("click", function () {
console.log("点击外部")
})
const list = document.getElementById("lesson-list")
list.addEventListener("click", function (event) {
const remove = event.target.closest(".remove-btn")
if (remove) {
const li = remove.closest(".lesson-item")
if (li) {
li.remove()
event.stopPropagation()
}
return
}
const tog = event.target.closest(".lesson-item")
if (tog) {
tog.classList.add("active")
}
})

View File

@@ -3,4 +3,24 @@
// 2. 点击按钮后清空旧日志
// 3. 先追加“开始执行”
// 4. 用 setTimeout 延迟追加“异步回调完成”
// 5. 再立刻追加“同步代码结束”
const btn = document.getElementById("run-btn")
const list = document.getElementById("log-list")
function add1(message) {
const li = document.createElement("li")
li.textContent = message
list.appendChild(li)
}
btn.addEventListener("click", function () {
list.textContent = ""
add1("开始执行")
setTimeout(function () {
add1("异步回调完成")
}, 2000)
add1("同步代码结束")
})

View File

@@ -12,3 +12,23 @@ function fakeFetchCourses() {
// 3. 调用 fakeFetchCourses()
// 4. 用 then 渲染课程列表
// 5. 用 catch 处理错误
const btn = document.getElementById("load-btn")
const text = document.getElementById("status-text")
const list = document.getElementById("course-list")
btn.addEventListener("click", function () {
text.textContent = "加载中..."
fakeFetchCourses()
.then(function (result) {
text.textContent = "加载成功"
const a = result.forEach(item => {
const li = document.createElement("li")
li.textContent = item
list.appendChild(li)
});
})
.catch(function (error) {
list.textContent = "失败" + error
})
})

View File

@@ -16,3 +16,24 @@ function fakeFetchUser() {
// 3. 用 await 等待 fakeFetchUser()
// 4. 渲染用户信息
// 5. 用 try...catch 处理异常
const btn = document.getElementById("load-user-btn")
const status = document.getElementById("user-status")
const card = document.getElementById("user-card")
async function a() {
status.textContent = "加载中"
card.innerHTML = ""
try {
const a = await fakeFetchUser()
status.textContent = "加载成功"
card.innerHTML = `
<p>姓名:${a.name}</p>
<p>角色:${a.role}</p>
<p>任务:${a.focus}</p>
`
} catch (error) {
status.textContent = "加载失败"
}
}
btn.addEventListener("click", a)

View File

@@ -20,3 +20,85 @@ function fakeLoadExtraLessons() {
// 3. 点击列表项时切换 done 状态
// 4. 提交表单时阻止默认提交,并新增课程
// 5. 点击加载按钮时显示加载状态,并把异步返回的课程追加到列表
/* 一个课程列表区域
- 一个表单区域
- 一个添加课程的交互
- 一个点击课程切换完成状态的交互
- 一个异步加载提示或远程数据模拟
- 清晰的状态文案更新*/
const page = document.querySelector(".page")
const hero = document.querySelector("hero")
const text = document.getElementById("status-text")
const panel = document.querySelector(".panel")
const btn = document.getElementById("load-btn")
const list = document.getElementById("lesson-list")
const formPanel = document.querySelector(".form-panel")
const lessonForm = document.getElementById("lesson-form")
const lessonInput = document.getElementById("lesson-input")
function renderLessons() {
lessons.forEach(item => {
const li = document.createElement("li")
li.classList.add("li")
li.setAttribute("title", item.title)
li.setAttribute("done", item.done)
li.textContent = `
标题:${item.title}
状态:${item.done}`
list.appendChild(li)
})
}
renderLessons()
//event.target,closest,
list.addEventListener("click", function (event) {
const a = event.target.closest(".li")
if (a) {
a.textContent = `
标题:${a.title}
状态:${!a.done}`
a.done = !a.done
}
})
lessonForm.addEventListener("submit", function (event) {
event.preventDefault()
const c = document.createElement("li")
const d = lessonInput.value.trim()
c.textContent = `
标题:${d}
状态true`
c.setAttribute("title", d)
c.setAttribute("done", true)
c.classList.add("li")
lessonInput.value = ""
list.appendChild(c)
})
async function load() {
text.textContent = "加载中"
text.innerHTML = ""
try {
const s = await fakeLoadExtraLessons()
text.textContent = "加载完成"
s.forEach(item => {
const li = document.createElement("li")
li.classList.add("li")
li.setAttribute("title", item.title)
li.setAttribute("done", item.done)
li.textContent = `
标题:${item.title}
状态:${item.done}`
list.appendChild(li)
})
} catch (error) {
text.textContent = "加载失败"
}
}
btn.addEventListener("click", load)

View File

@@ -4,3 +4,26 @@
// 3. 把输入内容实时渲染到右侧预览
// 4. 监听阶段下拉框的 change 事件
// 5. 更新阶段标签文字
const nickname = document.getElementById("nickname-input")
const goal = document.getElementById("goal-input")
const stage = document.getElementById("stage-select")
nickname.addEventListener("input", function () {
const previewName = document.getElementById("preview-name")
previewName.textContent = nickname.value
if (!nickname.value.trim()) {
previewName.textContent = "未填写昵称"
}
})
goal.addEventListener("input", function () {
const previewGoal = document.getElementById("preview-goal")
previewGoal.textContent = goal.value
if (!goal.value.trim()) {
previewGoal.textContent = "这里会显示你的学习目标。"
}
})
stage.addEventListener("change", function () {
const previewStage = document.getElementById("preview-stage")
previewStage.textContent = stage.value
})

View File

@@ -4,3 +4,26 @@
// 3. 点击 clear-active-btn 时移除所有 item 的 active 类名
// 4. 点击帮助链接时,用 preventDefault() 阻止跳转
// 5. 在提示文字里输出“已阻止默认跳转”
const prependBtn = document.getElementById("prepend-btn")
const clear = document.getElementById("clear-active-btn")
const helpLink = document.getElementById("help-link")
const hintText = document.getElementById("hint-text")
const messageList = document.getElementById("message-list")
prependBtn.addEventListener("click", function () {
const li = document.createElement("li")
li.classList.add("item")
messageList.prepend(li)
})
clear.addEventListener("click", function () {
const a = document.querySelectorAll("#message-list li")
a.forEach(item => {
item.classList.remove("active")
})
})
helpLink.addEventListener("click", function (event) {
event.preventDefault()
hintText.textContent = "已阻止默认跳转"
})

View File

@@ -9,3 +9,10 @@ const scores = [88, 92, 95];
// 1. 解构出 name、stage
// 2. 解构出前两个分数
// 3. 用模板字符串把信息写入 #output
const { name, stage } = student
const [a, b] = scores
const output = document.getElementById("output")
output.innerHTML = `
a = ${a}
b = ${b}
`

View File

@@ -7,6 +7,14 @@ const user = {
function sumScores(...scores) {
// 返回总分
/*let total = 0
scores.forEach(item => {
total = total+item
})
return total*/
return scores.reduce((acc, item) => {
return acc + item
}, 0)
}
// 任务:
@@ -14,3 +22,11 @@ function sumScores(...scores) {
// 2. 基于 user 生成一个 stage 为 "现代 JS" 的新对象
// 3. 调用 sumScores
// 4. 输出结果到 #output
const tracks1 = [...tracks, "ES6+"]
const user1 = {
...user,
stage: "现代 JS"
}
const sum = sumScores(1, 2, 3, 4)
const output = document.getElementById("output")
output.textContent = sum

View File

@@ -12,3 +12,7 @@ const tracks = ["DOM", "异步", "模块化"];
// 1. 把 getLevel 改成箭头函数
// 2. 把 add 改成箭头函数
// 3. 用 map + 箭头函数生成 ["[DOM]", ...]
const getLevel1 = score => score >= 80
const add1 = (a, b) => a + b
const tracks1 = tracks.map(item => `[${item}]`)
console.log(tracks1);

View File

@@ -1,4 +1,5 @@
# 练习 4模块基础
#
练习 4模块基础
## 目标
@@ -9,7 +10,6 @@
- `export`
- `import`
- `type="module"`
## 任务
- 从模块文件里导入课程数据和格式化函数

View File

@@ -1,3 +1,7 @@
// 任务:
// 1. 从 ./course-data.js 导入 courses 和 formatCourse
// 2. 把格式化后的结果写入 #output
import { courses, formatCourse } from "./course-data.js"
const a = courses.map(item => formatCourse(item))
const output = document.getElementById("output")
output.textContent = a

View File

@@ -10,3 +10,17 @@ function loadTracks() {
// 1. 调用 loadTracks()
// 2. 成功时更新状态和输出内容
// 3. 失败时更新状态
async function load() {
const status = document.getElementById("status")
status.textContent = "加载中"
try {
const a = await loadTracks()
status.textContent = "加载成功"
const output = document.getElementById("output")
output.textContent = a
} catch (error) {
status.textContent = "加载失败"
}
}
load()

View File

@@ -13,3 +13,16 @@ function loadConfig() {
// 1. 写一个 async 函数
// 2. 用 await 等待 loadConfig()
// 3. 用 try...catch 处理流程
async function load() {
const status = document.getElementById("status")
status.textContent = "加载中"
try {
const a = await loadConfig()
status.textContent = "加载成功"
const output = document.getElementById("output")
output.textContent = JSON.stringify(a)
} catch (error) {
status.textContent = "加载失败"
}
}
load()

View File

@@ -1,6 +1,11 @@
const trainer = {
name: "现代 JS 训练营",
report() {
setTimeout(() => {
const a = this.name
const output = document.getElementById("output")
output.textContent = a
}, 1000)
// 任务:
// 1. 用 setTimeout
// 2. 在回调里用箭头函数读取 this.name

View File

@@ -1,5 +1,5 @@
const loadButton = document.getElementById("load-btn");
const status = document.getElementById("status");
const status1 = document.getElementById("status");
const output = document.getElementById("output");
// 任务:
@@ -9,3 +9,17 @@ const output = document.getElementById("output");
// 4. 调用 res.json() 解析数据
// 5. 把 title 和 body 渲染到页面
// 6. 失败时显示“加载失败”
loadButton.addEventListener("click", async () => {
status1.textContent = "加载中..."
try {
let a = await fetch("https://jsonplaceholder.typicode.com/posts/1")
let data = await a.json()
status1.textContent = "加载成功"
const { title, body } = data
output.textContent = `title:${title}
body:${body}`
} catch (error) {
status1.textContent = "加载失败"
}
})

View File

@@ -5,3 +5,28 @@
// 4. 用展开运算符合并技能
// 5. 用模板字符串渲染标题和说明
// 6. 用 forEach 或 map + 箭头函数渲染列表
import { baseSummary, loadExtraSkills } from './summary-service.js'
async function get() {
const title = document.getElementById("title")
const intro = document.getElementById("intro")
title.textContent = '加载中...'
intro.innerHTML = ''
try {
let load = await loadExtraSkills()
title.textContent = '加载成功'
const { name, stage, skills } = baseSummary
intro.textContent = `
name:${name}
stage:${stage}`
load = [...load, ...skills]
load.forEach(item => {
const li = document.createElement("li")
const skillList = document.getElementById("skill-list")
li.textContent = item
skillList.appendChild(li)
});
} catch (error) {
title.textContent = '加载失败'
}
}
get()