
本文详解如何使用原生 JavaScript 为 <li> 元素绑定鼠标悬停与点击事件,实现 body 背景色实时切换,并进一步扩展为点击“Sign Out”时触发黑色背景 + 定位式气泡提示的完整交互效果。
本文详解如何使用原生 javascript 为 `
原始代码中存在两个关键错误:一是 getElementsByTagName("li") 返回的是 HTMLCollection(类数组对象),不支持直接调用 addEventListener();二是颜色值 "black" 和 "pink" 缺少引号,导致 JavaScript 解析为未定义变量而报错。
✅ 正确做法是使用 document.querySelectorAll("li") 获取所有 <li> 元素的 NodeList,再通过 forEach() 遍历并为每个元素分别绑定事件:
document.querySelectorAll("li").forEach(el => {
el.addEventListener("mouseover", () => {
document.body.style.backgroundColor = "black"; // 推荐使用 backgroundColor 更语义化
});
el.addEventListener("mouseout", () => {
document.body.style.backgroundColor = "pink";
});
});⚠️ 注意事项:
backgroundColor 比 background 更精准(后者可能覆盖 background-image、background-repeat 等复合属性);
-
若仅需对“Sign Out”链接生效(而非全部 <li>),应使用更精确的选择器,例如:
document.querySelector("#bottomlist li a[href$='index.html']").addEventListener("click", function(e) { e.preventDefault(); // 阻止默认跳转 document.body.style.backgroundColor = "black"; // 创建并定位气泡提示 showSpeechBubble(this); });
? 进阶:添加定位气泡提示(Speech Bubble)
为实现“点击后在原位置弹出黑色气泡”的效果,可动态创建一个绝对定位的 <div> 元素,并基于目标链接的 getBoundingClientRect() 计算坐标:
function showSpeechBubble(triggerEl) {
// 移除已存在的气泡(避免重复)
const existing = document.getElementById("tooltip-bubble");
if (existing) existing.remove();
const rect = triggerEl.getBoundingClientRect();
const bubble = document.createElement("div");
bubble.id = "tooltip-bubble";
bubble.textContent = "You are signing out...";
bubble.style.cssText = `
position: absolute;
background: #333;
color: white;
padding: 8px 12px;
border-radius: 6px;
font-size: 14px;
z-index: 1000;
top: ${rect.bottom + 8}px;
left: ${rect.left}px;
white-space: nowrap;
`;
// 添加小三角(伪元素方式)
const style = document.createElement("style");
style.textContent = `
#tooltip-bubble::after {
content: '';
position: absolute;
top: -6px;
left: 12px;
border: 6px solid transparent;
border-bottom-color: #333;
}
`;
document.head.appendChild(style);
document.body.appendChild(bubble);
// 3秒后自动移除
setTimeout(() => {
bubble.remove();
style.remove();
}, 3000);
}? 总结:
- ✅ 使用 querySelectorAll() + forEach() 替代 getElementsByTagName() 是操作多元素事件的基础;
- ✅ 所有 CSS 值(包括颜色)必须加引号;
- ✅ 点击跳转前务必调用 e.preventDefault();
- ✅ 气泡定位推荐结合 getBoundingClientRect() 实现像素级精准;
- ✅ 动态 DOM 操作后注意清理(如移除旧元素、清除定时器、卸载临时样式),保障性能与可维护性。

















