大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
Checkpoint: JavaScript 交互
你将完成什么
给个人主页加交互:导航栏滚动高亮、技能列表动态渲染、项目筛选、表单验证。
验收标准
- 用
addEventListener绑定事件 - 用
querySelector操作 DOM - 用数组方法(
map、filter)渲染列表 - 表单提交前验证
核心代码
导航高亮
const sections = document.querySelectorAll('section');
const navLinks = document.querySelectorAll('nav a');
window.addEventListener('scroll', () => {
let current = '';
sections.forEach(section => {
const sectionTop = section.offsetTop;
if (scrollY >= sectionTop - 60) {
current = section.getAttribute('id');
}
});
navLinks.forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href') === `#${current}`) {
link.classList.add('active');
}
});
});
技能动态渲染
const skills = ['HTML', 'CSS', 'JavaScript', 'React', 'Node.js'];
const skillsList = document.querySelector('#skills ul');
skills.forEach(skill => {
const li = document.createElement('li');
li.textContent = skill;
skillsList.appendChild(li);
});
项目筛选
const projects = [
{ id: 1, title: '学习平台', category: 'frontend' },
{ id: 2, title: 'API 服务', category: 'backend' },
{ id: 3, title: '全栈应用', category: 'fullstack' },
];
function renderProjects(category = 'all') {
const filtered = category === 'all'
? projects
: projects.filter(p => p.category === category);
const container = document.querySelector('#projects');
container.innerHTML = filtered.map(p => `
<article>
<h3>${p.title}</h3>
</article>
`).join('');
}
// 筛选按钮
document.querySelectorAll('.filter-btn').forEach(btn => {
btn.addEventListener('click', () => {
renderProjects(btn.dataset.category);
});
});
表单验证
const form = document.querySelector('#contact-form');
form.addEventListener('submit', (e) => {
e.preventDefault();
const email = form.email.value;
if (!email.includes('@')) {
alert('邮箱格式错误');
return;
}
console.log('提交成功:', email);
});
常见卡点
- DOM 未加载完成就执行:用
DOMContentLoaded或把<script>放</body>前。 this指向问题:用箭头函数或.bind(this)。- 动态添加的元素事件不生效:用事件委托(
addEventListener绑在父元素上)。
加分项
- 用
localStorage保存用户偏好(主题、语言) - 用
IntersectionObserver实现懒加载 - 防抖节流优化滚动事件
下一步
完成本课后,进入「npm 与构建工具」阶段,学习模块化开发。