Skip to content

HTML+CSS+JS联动实战

19.1 美化个人简介页面

项目目标

使用CSS美化个人简介页面,提升页面的视觉效果。

技术要点

  • HTML结构搭建
  • CSS样式美化
  • 响应式设计

实现代码

html
<!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>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            line-height: 1.6;
            color: #333;
            background-color: #f5f5f5;
        }
        
        .container {
            max-width: 900px;
            margin: 0 auto;
            padding: 20px;
        }
        
        .card {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border-radius: 15px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.1);
            overflow: hidden;
            margin-top: 50px;
        }
        
        .card-header {
            text-align: center;
            padding: 40px 20px;
            color: white;
        }
        
        .avatar {
            width: 150px;
            height: 150px;
            border-radius: 50%;
            border: 5px solid rgba(255,255,255,0.3);
            object-fit: cover;
            margin-bottom: 20px;
        }
        
        .name {
            font-size: 28px;
            font-weight: 700;
            margin-bottom: 10px;
        }
        
        .title {
            font-size: 18px;
            opacity: 0.9;
            margin-bottom: 20px;
        }
        
        .social-links {
            display: flex;
            justify-content: center;
            gap: 15px;
        }
        
        .social-link {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            background-color: rgba(255,255,255,0.2);
            color: white;
            text-decoration: none;
            transition: all 0.3s ease;
        }
        
        .social-link:hover {
            background-color: rgba(255,255,255,0.3);
            transform: translateY(-3px);
        }
        
        .card-body {
            background-color: white;
            padding: 40px;
        }
        
        .section {
            margin-bottom: 30px;
        }
        
        .section-title {
            font-size: 20px;
            font-weight: 600;
            color: #667eea;
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 2px solid #f0f0f0;
        }
        
        .info-list {
            list-style: none;
        }
        
        .info-item {
            margin-bottom: 10px;
            display: flex;
        }
        
        .info-label {
            font-weight: 600;
            width: 100px;
            color: #666;
        }
        
        .skills {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
        }
        
        .skill-item {
            background-color: #f0f0f0;
            padding: 8px 16px;
            border-radius: 20px;
            font-size: 14px;
            color: #666;
            transition: all 0.3s ease;
        }
        
        .skill-item:hover {
            background-color: #667eea;
            color: white;
        }
        
        .experience-item {
            margin-bottom: 20px;
        }
        
        .experience-title {
            font-weight: 600;
            margin-bottom: 5px;
        }
        
        .experience-meta {
            font-size: 14px;
            color: #666;
            margin-bottom: 10px;
        }
        
        @media (max-width: 768px) {
            .card-body {
                padding: 20px;
            }
            
            .info-item {
                flex-direction: column;
            }
            
            .info-label {
                width: 100%;
                margin-bottom: 5px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="card">
            <div class="card-header">
                <img src="https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=professional%20profile%20photo&image_size=square" alt="个人头像" class="avatar">
                <h1 class="name">张三</h1>
                <p class="title">前端开发工程师</p>
                <div class="social-links">
                    <a href="#" class="social-link">🔗</a>
                    <a href="#" class="social-link">📧</a>
                    <a href="#" class="social-link">📱</a>
                </div>
            </div>
            
            <div class="card-body">
                <div class="section">
                    <h2 class="section-title">个人简介</h2>
                    <p>我是一名前端开发工程师,热爱编程和技术创新。拥有2年前端开发经验,熟悉HTML、CSS、JavaScript等前端技术栈。</p>
                </div>
                
                <div class="section">
                    <h2 class="section-title">联系信息</h2>
                    <ul class="info-list">
                        <li class="info-item">
                            <span class="info-label">邮箱:</span>
                            <span>zhangsan@example.com</span>
                        </li>
                        <li class="info-item">
                            <span class="info-label">电话:</span>
                            <span>13800138000</span>
                        </li>
                        <li class="info-item">
                            <span class="info-label">地址:</span>
                            <span>北京市朝阳区</span>
                        </li>
                    </ul>
                </div>
                
                <div class="section">
                    <h2 class="section-title">技能</h2>
                    <div class="skills">
                        <span class="skill-item">HTML5</span>
                        <span class="skill-item">CSS3</span>
                        <span class="skill-item">JavaScript</span>
                        <span class="skill-item">React</span>
                        <span class="skill-item">Vue</span>
                        <span class="skill-item">Node.js</span>
                        <span class="skill-item">Git</span>
                        <span class="skill-item">UI设计</span>
                    </div>
                </div>
                
                <div class="section">
                    <h2 class="section-title">工作经验</h2>
                    <div class="experience-item">
                        <div class="experience-title">前端开发工程师</div>
                        <div class="experience-meta">2024年至今 | 某某科技有限公司</div>
                        <p>负责公司官网和内部系统的前端开发,使用React和Vue框架,参与项目的需求分析、设计和开发。</p>
                    </div>
                    <div class="experience-item">
                        <div class="experience-title">前端实习生</div>
                        <div class="experience-meta">2023年 | 某某互联网公司</div>
                        <p>参与公司产品的前端开发,学习并掌握了HTML、CSS、JavaScript等前端技术。</p>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

19.2 实现表单验证功能

项目目标

使用JavaScript实现表单验证功能,提升用户体验。

技术要点

  • HTML表单结构
  • JavaScript表单验证
  • 实时验证反馈

实现代码

html
<!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>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            line-height: 1.6;
            color: #333;
            background-color: #f5f5f5;
        }
        
        .container {
            max-width: 600px;
            margin: 0 auto;
            padding: 20px;
        }
        
        .form-container {
            background-color: white;
            border-radius: 10px;
            box-shadow: 0 5px 20px rgba(0,0,0,0.1);
            padding: 30px;
            margin-top: 50px;
        }
        
        h1 {
            text-align: center;
            color: #333;
            margin-bottom: 30px;
        }
        
        .form-group {
            margin-bottom: 20px;
        }
        
        label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #555;
        }
        
        input {
            width: 100%;
            padding: 12px;
            border: 2px solid #ddd;
            border-radius: 6px;
            font-size: 16px;
            transition: all 0.3s ease;
        }
        
        input:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
        }
        
        input.success {
            border-color: #28a745;
        }
        
        input.error {
            border-color: #dc3545;
        }
        
        .error-message {
            color: #dc3545;
            font-size: 14px;
            margin-top: 5px;
            min-height: 20px;
        }
        
        .btn {
            width: 100%;
            padding: 15px;
            background-color: #667eea;
            color: white;
            border: none;
            border-radius: 6px;
            font-size: 18px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
        }
        
        .btn:hover {
            background-color: #5a6fd8;
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
        }
        
        .btn:active {
            transform: translateY(0);
        }
        
        @media (max-width: 768px) {
            .form-container {
                padding: 20px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="form-container">
            <h1>用户注册</h1>
            <form id="registration-form">
                <div class="form-group">
                    <label for="username">用户名</label>
                    <input type="text" id="username" name="username" placeholder="请输入用户名">
                    <div class="error-message" id="username-error"></div>
                </div>
                
                <div class="form-group">
                    <label for="email">邮箱</label>
                    <input type="email" id="email" name="email" placeholder="请输入邮箱">
                    <div class="error-message" id="email-error"></div>
                </div>
                
                <div class="form-group">
                    <label for="password">密码</label>
                    <input type="password" id="password" name="password" placeholder="请输入密码">
                    <div class="error-message" id="password-error"></div>
                </div>
                
                <div class="form-group">
                    <label for="confirm-password">确认密码</label>
                    <input type="password" id="confirm-password" name="confirm-password" placeholder="请确认密码">
                    <div class="error-message" id="confirm-password-error"></div>
                </div>
                
                <button type="submit" class="btn">注册</button>
            </form>
        </div>
    </div>
    
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const form = document.getElementById('registration-form');
            const username = document.getElementById('username');
            const email = document.getElementById('email');
            const password = document.getElementById('password');
            const confirmPassword = document.getElementById('confirm-password');
            
            // 实时验证
            username.addEventListener('input', validateUsername);
            email.addEventListener('input', validateEmail);
            password.addEventListener('input', validatePassword);
            confirmPassword.addEventListener('input', validateConfirmPassword);
            
            // 表单提交
            form.addEventListener('submit', function(e) {
                e.preventDefault();
                
                const isUsernameValid = validateUsername();
                const isEmailValid = validateEmail();
                const isPasswordValid = validatePassword();
                const isConfirmPasswordValid = validateConfirmPassword();
                
                if (isUsernameValid && isEmailValid && isPasswordValid && isConfirmPasswordValid) {
                    alert('注册成功!');
                    form.reset();
                }
            });
            
            function validateUsername() {
                const usernameValue = username.value.trim();
                const usernameError = document.getElementById('username-error');
                
                if (usernameValue === '') {
                    setError(username, usernameError, '用户名不能为空');
                    return false;
                } else if (usernameValue.length < 3) {
                    setError(username, usernameError, '用户名长度不能少于3位');
                    return false;
                } else {
                    setSuccess(username, usernameError);
                    return true;
                }
            }
            
            function validateEmail() {
                const emailValue = email.value.trim();
                const emailError = document.getElementById('email-error');
                const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
                
                if (emailValue === '') {
                    setError(email, emailError, '邮箱不能为空');
                    return false;
                } else if (!emailRegex.test(emailValue)) {
                    setError(email, emailError, '请输入有效的邮箱地址');
                    return false;
                } else {
                    setSuccess(email, emailError);
                    return true;
                }
            }
            
            function validatePassword() {
                const passwordValue = password.value;
                const passwordError = document.getElementById('password-error');
                
                if (passwordValue === '') {
                    setError(password, passwordError, '密码不能为空');
                    return false;
                } else if (passwordValue.length < 6) {
                    setError(password, passwordError, '密码长度不能少于6位');
                    return false;
                } else if (!/[A-Z]/.test(passwordValue)) {
                    setError(password, passwordError, '密码必须包含至少一个大写字母');
                    return false;
                } else if (!/[0-9]/.test(passwordValue)) {
                    setError(password, passwordError, '密码必须包含至少一个数字');
                    return false;
                } else {
                    setSuccess(password, passwordError);
                    return true;
                }
            }
            
            function validateConfirmPassword() {
                const confirmPasswordValue = confirmPassword.value;
                const confirmPasswordError = document.getElementById('confirm-password-error');
                
                if (confirmPasswordValue === '') {
                    setError(confirmPassword, confirmPasswordError, '请确认密码');
                    return false;
                } else if (confirmPasswordValue !== password.value) {
                    setError(confirmPassword, confirmPasswordError, '两次输入的密码不一致');
                    return false;
                } else {
                    setSuccess(confirmPassword, confirmPasswordError);
                    return true;
                }
            }
            
            function setError(input, errorElement, message) {
                input.classList.remove('success');
                input.classList.add('error');
                errorElement.textContent = message;
            }
            
            function setSuccess(input, errorElement) {
                input.classList.remove('error');
                input.classList.add('success');
                errorElement.textContent = '';
            }
        });
    </script>
</body>
</html>

19.3 制作图片切换页面

项目目标

使用JavaScript实现图片切换功能,提升用户交互体验。

技术要点

  • HTML图片结构
  • JavaScript事件处理
  • 图片切换逻辑

实现代码

html
<!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>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            line-height: 1.6;
            color: #333;
            background-color: #f5f5f5;
        }
        
        .container {
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        
        .gallery {
            background-color: white;
            border-radius: 10px;
            box-shadow: 0 5px 20px rgba(0,0,0,0.1);
            padding: 30px;
            margin-top: 50px;
            text-align: center;
        }
        
        h1 {
            margin-bottom: 30px;
            color: #333;
        }
        
        .image-container {
            position: relative;
            margin-bottom: 30px;
            height: 400px;
            overflow: hidden;
            border-radius: 10px;
        }
        
        .image-container img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            transition: all 0.5s ease;
        }
        
        .image-container img.fade-in {
            animation: fadeIn 0.5s ease-in-out;
        }
        
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }
        
        .controls {
            display: flex;
            justify-content: center;
            gap: 15px;
            margin-bottom: 30px;
        }
        
        .btn {
            padding: 10px 20px;
            background-color: #667eea;
            color: white;
            border: none;
            border-radius: 6px;
            font-size: 16px;
            cursor: pointer;
            transition: all 0.3s ease;
        }
        
        .btn:hover {
            background-color: #5a6fd8;
            transform: translateY(-2px);
        }
        
        .btn:disabled {
            background-color: #ccc;
            cursor: not-allowed;
            transform: none;
        }
        
        .thumbnails {
            display: flex;
            gap: 10px;
            justify-content: center;
            flex-wrap: wrap;
        }
        
        .thumbnail {
            width: 80px;
            height: 80px;
            border-radius: 6px;
            cursor: pointer;
            overflow: hidden;
            border: 3px solid transparent;
            transition: all 0.3s ease;
        }
        
        .thumbnail img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
        
        .thumbnail.active {
            border-color: #667eea;
            transform: scale(1.1);
        }
        
        @media (max-width: 768px) {
            .gallery {
                padding: 20px;
            }
            
            .image-container {
                height: 300px;
            }
            
            .thumbnail {
                width: 60px;
                height: 60px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="gallery">
            <h1>图片切换展示</h1>
            
            <div class="image-container">
                <img id="main-image" src="https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=beautiful%20landscape%201&image_size=landscape_16_9" alt="图片1">
            </div>
            
            <div class="controls">
                <button id="prev-btn" class="btn">上一张</button>
                <button id="next-btn" class="btn">下一张</button>
                <button id="play-btn" class="btn">播放</button>
            </div>
            
            <div class="thumbnails">
                <div class="thumbnail active" data-index="0">
                    <img src="https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=beautiful%20landscape%201&image_size=square" alt="缩略图1">
                </div>
                <div class="thumbnail" data-index="1">
                    <img src="https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=beautiful%20landscape%202&image_size=square" alt="缩略图2">
                </div>
                <div class="thumbnail" data-index="2">
                    <img src="https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=beautiful%20landscape%203&image_size=square" alt="缩略图3">
                </div>
                <div class="thumbnail" data-index="3">
                    <img src="https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=beautiful%20landscape%204&image_size=square" alt="缩略图4">
                </div>
            </div>
        </div>
    </div>
    
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const images = [
                "https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=beautiful%20landscape%201&image_size=landscape_16_9",
                "https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=beautiful%20landscape%202&image_size=landscape_16_9",
                "https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=beautiful%20landscape%203&image_size=landscape_16_9",
                "https://trae-api-cn.mchost.guru/api/ide/v1/text_to_image?prompt=beautiful%20landscape%204&image_size=landscape_16_9"
            ];
            
            let currentIndex = 0;
            let slideInterval;
            let isPlaying = false;
            
            const mainImage = document.getElementById('main-image');
            const prevBtn = document.getElementById('prev-btn');
            const nextBtn = document.getElementById('next-btn');
            const playBtn = document.getElementById('play-btn');
            const thumbnails = document.querySelectorAll('.thumbnail');
            
            // 初始化
            updateImage();
            
            // 上一张
            prevBtn.addEventListener('click', function() {
                currentIndex = (currentIndex - 1 + images.length) % images.length;
                updateImage();
            });
            
            // 下一张
            nextBtn.addEventListener('click', function() {
                currentIndex = (currentIndex + 1) % images.length;
                updateImage();
            });
            
            // 播放/暂停
            playBtn.addEventListener('click', function() {
                if (isPlaying) {
                    clearInterval(slideInterval);
                    playBtn.textContent = '播放';
                } else {
                    slideInterval = setInterval(function() {
                        currentIndex = (currentIndex + 1) % images.length;
                        updateImage();
                    }, 3000);
                    playBtn.textContent = '暂停';
                }
                isPlaying = !isPlaying;
            });
            
            // 缩略图点击
            thumbnails.forEach(function(thumbnail) {
                thumbnail.addEventListener('click', function() {
                    currentIndex = parseInt(this.getAttribute('data-index'));
                    updateImage();
                });
            });
            
            function updateImage() {
                // 更新主图片
                mainImage.src = images[currentIndex];
                mainImage.classList.add('fade-in');
                setTimeout(function() {
                    mainImage.classList.remove('fade-in');
                }, 500);
                
                // 更新缩略图状态
                thumbnails.forEach(function(thumbnail, index) {
                    if (index === currentIndex) {
                        thumbnail.classList.add('active');
                    } else {
                        thumbnail.classList.remove('active');
                    }
                });
            }
        });
    </script>
</body>
</html>

19.4 搭建响应式导航栏

项目目标

使用HTML和CSS搭建响应式导航栏,适配不同设备屏幕。

技术要点

  • HTML导航结构
  • CSS响应式设计
  • JavaScript菜单切换

实现代码

html
<!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>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            line-height: 1.6;
            color: #333;
            background-color: #f5f5f5;
        }
        
        header {
            background-color: #333;
            position: sticky;
            top: 0;
            z-index: 1000;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        
        .navbar {
            max-width: 1200px;
            margin: 0 auto;
            padding: 0 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            height: 70px;
        }
        
        .logo {
            color: white;
            font-size: 24px;
            font-weight: 700;
            text-decoration: none;
        }
        
        .nav-links {
            display: flex;
            list-style: none;
            gap: 20px;
        }
        
        .nav-links li a {
            color: white;
            text-decoration: none;
            font-size: 16px;
            font-weight: 500;
            transition: all 0.3s ease;
            padding: 8px 16px;
            border-radius: 4px;
        }
        
        .nav-links li a:hover {
            background-color: rgba(255,255,255,0.1);
        }
        
        .nav-links li a.active {
            background-color: #667eea;
        }
        
        .menu-toggle {
            display: none;
            cursor: pointer;
            color: white;
            font-size: 24px;
        }
        
        .hero {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            text-align: center;
            padding: 100px 20px;
        }
        
        .hero h1 {
            font-size: 48px;
            margin-bottom: 20px;
        }
        
        .hero p {
            font-size: 20px;
            margin-bottom: 30px;
            opacity: 0.9;
        }
        
        .btn {
            display: inline-block;
            padding: 12px 30px;
            background-color: white;
            color: #667eea;
            text-decoration: none;
            border-radius: 6px;
            font-weight: 600;
            transition: all 0.3s ease;
        }
        
        .btn:hover {
            transform: translateY(-3px);
            box-shadow: 0 5px 15px rgba(0,0,0,0.1);
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 50px 20px;
        }
        
        .section {
            margin-bottom: 50px;
        }
        
        .section h2 {
            font-size: 32px;
            margin-bottom: 20px;
            color: #333;
        }
        
        @media (max-width: 768px) {
            .menu-toggle {
                display: block;
            }
            
            .nav-links {
                position: absolute;
                top: 70px;
                left: 0;
                width: 100%;
                background-color: #333;
                flex-direction: column;
                align-items: center;
                padding: 20px 0;
                gap: 15px;
                box-shadow: 0 5px 10px rgba(0,0,0,0.1);
                transform: translateY(-100%);
                opacity: 0;
                pointer-events: none;
                transition: all 0.3s ease;
            }
            
            .nav-links.active {
                transform: translateY(0);
                opacity: 1;
                pointer-events: all;
            }
            
            .hero h1 {
                font-size: 36px;
            }
            
            .hero p {
                font-size: 18px;
            }
        }
    </style>
</head>
<body>
    <header>
        <nav class="navbar">
            <a href="#" class="logo">Logo</a>
            <ul class="nav-links">
                <li><a href="#" class="active">首页</a></li>
                <li><a href="#">关于我们</a></li>
                <li><a href="#">产品中心</a></li>
                <li><a href="#">服务项目</a></li>
                <li><a href="#">联系我们</a></li>
            </ul>
            <div class="menu-toggle">☰</div>
        </nav>
    </header>
    
    <section class="hero">
        <h1>欢迎访问我们的网站</h1>
        <p>这是一个响应式导航栏示例,适配不同设备屏幕</p>
        <a href="#" class="btn">了解更多</a>
    </section>
    
    <div class="container">
        <section class="section">
            <h2>关于我们</h2>
            <p>我们是一家专注于前端开发的公司,致力于为客户提供高质量的网站和应用解决方案。我们拥有专业的开发团队,能够满足各种复杂的开发需求。</p>
        </section>
        
        <section class="section">
            <h2>我们的服务</h2>
            <p>我们提供网站开发、应用开发、UI设计等多种服务,能够根据客户的需求提供定制化的解决方案。我们注重用户体验和代码质量,确保每一个项目都能够达到客户的期望。</p>
        </section>
    </div>
    
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const menuToggle = document.querySelector('.menu-toggle');
            const navLinks = document.querySelector('.nav-links');
            
            menuToggle.addEventListener('click', function() {
                navLinks.classList.toggle('active');
            });
            
            // 点击导航链接后关闭菜单
            document.querySelectorAll('.nav-links a').forEach(function(link) {
                link.addEventListener('click', function() {
                    navLinks.classList.remove('active');
                });
            });
        });
    </script>
</body>
</html>

小结

通过本章节的学习,你已经完成了几个HTML+CSS+JS联动的实战项目,包括美化个人简介页面、实现表单验证功能、制作图片切换页面和搭建响应式导航栏。这些项目涵盖了前端开发的核心技能,通过实战练习,你可以巩固所学的HTML、CSS和JavaScript知识,提升实战能力,为将来的前端开发工作打下坚实的基础。

© 2026 编程马·菜鸟教程 版权所有