feat: add TypeScript lessons and learning panel
- Introduced a new script to check TypeScript lesson files for errors. - Created a main TypeScript file to render lessons and their details. - Added lesson definitions with starter and answer codes. - Implemented a user interface for navigating and running lessons. - Styled the application with CSS for a better user experience. - Updated README to reflect the new TypeScript section and usage instructions.
This commit is contained in:
25
04-dom-events-async/06-bubbling-and-delegation/README.md
Normal file
25
04-dom-events-async/06-bubbling-and-delegation/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# 练习 6:冒泡、委托和 stopPropagation
|
||||
|
||||
## 目标
|
||||
|
||||
理解事件会冒泡,并学会在列表里使用事件委托。
|
||||
|
||||
## 你要练什么
|
||||
|
||||
- 事件冒泡
|
||||
- `event.target`
|
||||
- 事件委托
|
||||
- `stopPropagation()`
|
||||
|
||||
## 任务
|
||||
|
||||
- 点击外层面板时输出一条日志
|
||||
- 点击列表项时,通过事件委托切换激活状态
|
||||
- 点击列表项里的删除按钮时,阻止冒泡并删除当前项
|
||||
|
||||
## 文件
|
||||
|
||||
- [starter.html](/Users/lijiaqing/home/wwwroot/front-end-example/04-dom-events-async/06-bubbling-and-delegation/starter.html)
|
||||
- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/04-dom-events-async/06-bubbling-and-delegation/starter.js)
|
||||
- [answer.html](/Users/lijiaqing/home/wwwroot/front-end-example/04-dom-events-async/06-bubbling-and-delegation/answer.html)
|
||||
- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/04-dom-events-async/06-bubbling-and-delegation/answer.js)
|
||||
58
04-dom-events-async/06-bubbling-and-delegation/answer.html
Normal file
58
04-dom-events-async/06-bubbling-and-delegation/answer.html
Normal file
@@ -0,0 +1,58 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>冒泡、委托和 stopPropagation</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 32px;
|
||||
font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
background: #f5f7fb;
|
||||
}
|
||||
|
||||
.panel {
|
||||
max-width: 760px;
|
||||
margin: 0 auto;
|
||||
padding: 24px;
|
||||
border-radius: 20px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #dbe2ee;
|
||||
}
|
||||
|
||||
.lesson-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 14px;
|
||||
border: 1px solid #dbe2ee;
|
||||
border-radius: 12px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.lesson-item.active {
|
||||
background: #dbeafe;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<section id="panel" class="panel">
|
||||
<h1>事件委托练习</h1>
|
||||
<p>点击列表项可以切换高亮,点击删除按钮可以移除当前项。</p>
|
||||
|
||||
<ul id="lesson-list">
|
||||
<li class="lesson-item">
|
||||
<span>事件冒泡</span>
|
||||
<button class="remove-btn" type="button">删除</button>
|
||||
</li>
|
||||
<li class="lesson-item">
|
||||
<span>事件委托</span>
|
||||
<button class="remove-btn" type="button">删除</button>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<script src="./answer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
27
04-dom-events-async/06-bubbling-and-delegation/answer.js
Normal file
27
04-dom-events-async/06-bubbling-and-delegation/answer.js
Normal file
@@ -0,0 +1,27 @@
|
||||
const panel = document.getElementById("panel");
|
||||
const lessonList = document.getElementById("lesson-list");
|
||||
|
||||
panel.addEventListener("click", function () {
|
||||
console.log("点击到了外层面板");
|
||||
});
|
||||
|
||||
lessonList.addEventListener("click", function (event) {
|
||||
const removeButton = event.target.closest(".remove-btn");
|
||||
|
||||
if (removeButton) {
|
||||
event.stopPropagation();
|
||||
const currentItem = removeButton.closest(".lesson-item");
|
||||
|
||||
if (currentItem) {
|
||||
currentItem.remove();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const currentItem = event.target.closest(".lesson-item");
|
||||
|
||||
if (currentItem) {
|
||||
currentItem.classList.toggle("active");
|
||||
}
|
||||
});
|
||||
58
04-dom-events-async/06-bubbling-and-delegation/starter.html
Normal file
58
04-dom-events-async/06-bubbling-and-delegation/starter.html
Normal file
@@ -0,0 +1,58 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>冒泡、委托和 stopPropagation</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 32px;
|
||||
font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
background: #f5f7fb;
|
||||
}
|
||||
|
||||
.panel {
|
||||
max-width: 760px;
|
||||
margin: 0 auto;
|
||||
padding: 24px;
|
||||
border-radius: 20px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #dbe2ee;
|
||||
}
|
||||
|
||||
.lesson-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 14px;
|
||||
border: 1px solid #dbe2ee;
|
||||
border-radius: 12px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.lesson-item.active {
|
||||
background: #dbeafe;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<section id="panel" class="panel">
|
||||
<h1>事件委托练习</h1>
|
||||
<p>点击列表项可以切换高亮,点击删除按钮可以移除当前项。</p>
|
||||
|
||||
<ul id="lesson-list">
|
||||
<li class="lesson-item">
|
||||
<span>事件冒泡</span>
|
||||
<button class="remove-btn" type="button">删除</button>
|
||||
</li>
|
||||
<li class="lesson-item">
|
||||
<span>事件委托</span>
|
||||
<button class="remove-btn" type="button">删除</button>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<script src="./starter.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,5 @@
|
||||
// 任务:
|
||||
// 1. 给 panel 绑定点击事件,输出一条日志
|
||||
// 2. 给 lesson-list 绑定点击事件,使用事件委托
|
||||
// 3. 点击 li 时切换 active 类名
|
||||
// 4. 点击删除按钮时,阻止冒泡并删除当前 li
|
||||
Reference in New Issue
Block a user