第二十八天:事件与综合项目 — 响应交互的"设备管理系统"
蜗牛往上爬 · 前端工业可视化学习笔记 第 28 篇
DOM 让 JS 能改页面,事件让页面能"响应"用户——点击、输入、键盘。今天学 addEventListener、事件对象、事件冒泡与委托,最后用全部所学(对象数组 + DOM + 事件)完成 JS 基础收官项目:设备管理系统(增删改查)。
目录
一、addEventListener 添加监听
var btn = document.getElementById("add-btn");
// 添加监听
btn.addEventListener("click", function () {
console.log("按钮被点击");
});
addEventListener vs onclick:
// onclick:只能绑一个(后者覆盖前者)
btn.onclick = fn1;
btn.onclick = fn2; // 覆盖 fn1
// addEventListener:能绑多个(都执行)
btn.addEventListener("click", fn1);
btn.addEventListener("click", fn2); // 两个都执行
推荐 addEventListener:可绑多个、可移除(removeEventListener)。
二、常用事件速查
// 鼠标事件
element.addEventListener("click", fn); // 单击
element.addEventListener("dblclick", fn); // 双击
element.addEventListener("mouseover", fn); // 移入
element.addEventListener("mouseout", fn); // 移出
// 键盘事件
document.addEventListener("keydown", function (e) {
console.log(e.key); // "Enter"、"a"...
if (e.key === "Enter") { /* 回车 */ }
});
// 表单事件
input.addEventListener("input", function (e) {
console.log(e.target.value); // 实时输入值
});
form.addEventListener("submit", function (e) {
e.preventDefault(); // ⭐ 阻止表单默认提交(刷新页面)
// 处理提交
});
// 窗口事件
window.addEventListener("resize", fn); // 窗口大小变化
三、事件对象 event
card.addEventListener("click", function (event) {
event.target; // 实际被点击的元素
event.currentTarget; // 绑定监听的元素
event.type; // "click"
event.preventDefault(); // 阻止默认行为(a 跳转、表单提交)
event.stopPropagation(); // 阻止冒泡
});
四、事件冒泡与事件委托
冒泡:点击子元素,事件会一路冒泡到父元素。
<div id="list">
<div class="card">设备A</div>
<div class="card">设备B</div>
</div>
// 点击"设备A"时冒泡顺序:card → #list → body → ... → document
// ⭐ 事件委托:把监听绑到父元素,处理所有子元素
var list = document.getElementById("list");
list.addEventListener("click", function (event) {
var target = event.target;
if (target.classList.contains("card")) {
console.log("点击了:" + target.textContent);
}
});
// 之后动态添加的新卡片,无需再绑定,自动生效 ✅
var newCard = document.createElement("div");
newCard.className = "card";
newCard.textContent = "设备C";
list.appendChild(newCard); // 点击它也能触发上面的监听
事件委托的价值:
动态添加的元素自动响应
几百个卡片只绑 1 个监听(性能好)
代码简洁
五、定时器:让数据动起来
// setTimeout:延迟一次
setTimeout(function () { console.log("3 秒后"); }, 3000);
// setInterval:周期执行
var timer = setInterval(function () { console.log("每秒一次"); }, 1000);
clearInterval(timer); // 停止
// 实战:大屏时间实时更新
function updateTime() {
document.getElementById("current-time").textContent =
new Date().toLocaleString();
}
updateTime();
setInterval(updateTime, 1000);
六、综合项目:设备管理系统
JS 基础收官项目——对象数组 + DOM + 事件 + 事件委托的完整应用。
HTML
<h1>设备管理系统</h1>
<!-- 添加表单 -->
<form id="device-form">
<input id="input-id" placeholder="设备编号" required>
<input id="input-name" placeholder="设备名称" required>
<button type="submit">添加</button>
</form>
<!-- 搜索 -->
<input id="search-input" placeholder="搜索设备名称...">
<!-- 列表 -->
<ul id="device-list"></ul>
<script src="device-manager.js"></script>
JS
// ========== 数据层 ==========
var devices = [
{ id: "CNC-001", name: "数控机床" },
{ id: "AGV-002", name: "搬运机器人" }
];
// ========== 渲染层 ==========
function render(filterText) {
var list = document.getElementById("device-list");
list.innerHTML = "";
// 搜索过滤
var data = filterText
? devices.filter(function (d) {
return d.name.indexOf(filterText) !== -1;
})
: devices;
// 渲染
data.forEach(function (device) {
var li = document.createElement("li");
li.innerHTML =
"<span>" + device.id + " - " + device.name + "</span>" +
"<button class='del' data-id='" + device.id + "'>删除</button>";
list.appendChild(li);
});
}
// ========== 添加设备 ==========
document.getElementById("device-form").addEventListener("submit", function (e) {
e.preventDefault(); // 阻止刷新
var id = document.getElementById("input-id").value.trim();
var name = document.getElementById("input-name").value.trim();
if (!id || !name) return alert("编号和名称不能为空");
// 查重
if (devices.some(function (d) { return d.id === id; })) {
return alert("编号已存在");
}
devices.push({ id: id, name: name });
this.reset();
render();
});
// ========== 删除设备(事件委托)==========
document.getElementById("device-list").addEventListener("click", function (e) {
if (!e.target.classList.contains("del")) return;
var id = e.target.getAttribute("data-id");
devices = devices.filter(function (d) { return d.id !== id; });
render();
});
// ========== 搜索 ==========
document.getElementById("search-input").addEventListener("input", function (e) {
render(e.target.value.trim());
});
// 首次渲染
render();
这个项目用到的知识点:
七、总结
🎉 设备管理系统完成,JS 基础(语法 + 数据结构 + 逻辑 + DOM + 事件)全部收官!接下来进入 ES6 标准——用更现代简洁的语法(let/const、箭头函数、模板字符串)重写这些代码。