大学生常用-原生js实现:点击切换图片,轮播图,tab切换,分页符,秒杀等等......直接copy就能使

7 阅读10分钟

目录

一、交互组件类

轮播图实现

Tab切换功能

模态框 (Modal)

下拉菜单

手风琴效果

自定义右键菜单

二、表单处理类

表单验证增强

密码强度检测(输入安全相关)

三、数据存储类

本地存储记忆功能(localStorage/cookie操作)

四、动态内容处理

实时搜索过滤

动态加载更多内容

随机名言生成器

五、实用工具类

网页计时器/倒计时

复制到剪贴板

简易画板功能(图形交互工具)

六、用户体验优化

回到顶部按钮

图片懒加载(性能优化)

  原生js图片放大镜效果

暗黑模式切换

网页主题色切换

七、视觉效果类

点击切换图片(基础视觉交互)

滚动动画触发

视差滚动效果


除了以下功能,还想要什么功能可写评论,作者大大看到就会回复哦

一、交互组件类

轮播图实现

 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>轮播图示例</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="carousel">
        ![404](images/image1.jpg)
        ![457](images/image2.jpg)
        ![495](images/image3.jpg)
        <!-- 可以继续添加更多图片 -->
        <div class="controls">
            <button id="prev">Prev</button>
            <button id="next">Next</button>
        </div>
    </div>
    <script src="script.js"></script>
</body>
</html>

styles.css

.carousel {
    position: relative;
    width: 600px;
    height: 400px;
    overflow: hidden;
    margin: 0 auto;
    border: 2px solid #ddd;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.carousel img {
    width: 100%;
    height: 100%;
    display: none;
    transition: opacity 0.5s ease;
}

.carousel img.active {
    display: block;
    opacity: 1;
}

.controls {
    position: absolute;
    top: 50%;
    width: 100%;
    display: flex;
    justify-content: space-between;
    transform: translateY(-50%);
}

.controls button {
    background-color: rgba(0, 0, 0, 0.5);
    color: white;
    border: none;
    padding: 10px;
    cursor: pointer;
    border-radius: 5px;
    transition: background-color 0.3s ease;
}

.controls button:hover {
    background-color: rgba(0, 0, 0, 0.7);
}

script.js

document.addEventListener('DOMContentLoaded', () => {
    let currentIndex = 0;
    const images = document.querySelectorAll('.carousel img');
    const prevButton = document.getElementById('prev');
    const nextButton = document.getElementById('next');

    function showImage(index) {
        images.forEach((img, i) => {
            img.classList.toggle('active', i === index);
        });
    }

    function showNextImage() {
        currentIndex = (currentIndex + 1) % images.length;
        showImage(currentIndex);
    }

    function showPrevImage() {
        currentIndex = (currentIndex - 1 + images.length) % images.length;
        showImage(currentIndex);
    }

    nextButton.addEventListener('click', showNextImage);
    prevButton.addEventListener('click', showPrevImage);

    // 自动播放功能(可选)
    setInterval(showNextImage, 3000); // 每3秒切换一次图片

    // 添加淡入淡出效果
    images.forEach(img => {
        img.addEventListener('transitionend', () => {
            if (!img.classList.contains('active')) {
                img.style.opacity = 0;
            }
        });
    });

    // 初始化时设置非活动图片的透明度
    images.forEach((img, i) => {
        if (i !== currentIndex) {
            img.style.opacity = 0;
        }
    });
});

Tab切换功能

 html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tab Switch</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="tabs">
        <button class="tab-button" data-tab="1">Tab 1</button>
        <button class="tab-button" data-tab="2">Tab 2</button>
        <button class="tab-button" data-tab="3">Tab 3</button>
    </div>
    <div class="tab-content">
        <div class="tab-pane" id="tab-1">Content for Tab 1</div>
        <div class="tab-pane" id="tab-2">Content for Tab 2</div>
        <div class="tab-pane" id="tab-3">Content for Tab 3</div>
    </div>
    <script src="script.js"></script>
</body>
</html>

css

/* styles.css */
body {
    font-family: Arial, sans-serif;
}

.tabs {
    display: flex;
    margin-bottom: 20px;
}

.tab-button {
    padding: 10px 20px;
    margin-right: 5px;
    background-color: #f0f0f0;
    border: 1px solid #ccc;
    cursor: pointer;
}

.tab-button:hover {
    background-color: #e0e0e0;
}

.tab-pane {
    display: none;
    padding: 20px;
    border: 1px solid #ccc;
    border-radius: 5px;
}

.tab-pane.active {
    display: block;
}

js

// script.js
document.addEventListener('DOMContentLoaded', function() {
    const tabButtons = document.querySelectorAll('.tab-button');
    const tabPanes = document.querySelectorAll('.tab-pane');

    tabButtons.forEach(button => {
        button.addEventListener('click', function() {
            tabButtons.forEach(b => b.classList.remove('active'));
            tabPanes.forEach(p => p.classList.remove('active'));

            const tabId = this.getAttribute('data-tab');
            this.classList.add('active');
            document.getElementById(`tab-${tabId}`).classList.add('active');
        });
    });

    if (tabButtons.length > 0) {
        tabButtons[0].click();
    }
});

模态框 (Modal)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>模态框示例</title>
  <style>
    .modal {
      display: none;
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.5);
      z-index: 1000;
    }
    .modal-content {
      position: relative;
      margin: 10% auto;
      padding: 20px;
      width: 80%;
      max-width: 500px;
      background-color: white;
      border-radius: 5px;
    }
    .close {
      position: absolute;
      top: 10px;
      right: 15px;
      font-size: 24px;
      cursor: pointer;
    }
    .open-modal {
      padding: 10px 20px;
      background-color: #4CAF50;
      color: white;
      border: none;
      border-radius: 5px;
      cursor: pointer;
    }
  </style>
</head>
<body>
  <button class="open-modal">打开模态框</button>
  <div id="modal" class="modal">
    <div class="modal-content">
      <span class="close">&times;</span>
      <h2>模态框标题</h2>
      <p>这是一个模态框内容。</p>
    </div>
  </div>
  <script>
    const modal = document.getElementById('modal');
    const openBtn = document.querySelector('.open-modal');
    const closeBtn = document.querySelector('.close');

    openBtn.onclick = () => {
      modal.style.display = 'block';
    };

    closeBtn.onclick = () => {
      modal.style.display = 'none';
    };

    window.onclick = (e) => {
      if (e.target === modal) {
        modal.style.display = 'none';
      }
    };
  </script>
</body>
</html>

下拉菜单

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>下拉菜单示例</title>
  <style>
    .dropdown {
      position: relative;
      display: inline-block;
    }
    .dropdown-content {
      display: none;
      position: absolute;
      background-color: white;
      min-width: 160px;
      box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
      z-index: 1;
    }
    .dropdown-content a {
      color: black;
      padding: 12px 16px;
      text-decoration: none;
      display: block;
    }
    .dropdown-content.show {
      display: block;
    }
    .dropdown-btn {
      padding: 10px 20px;
      background-color: #4CAF50;
      color: white;
      border: none;
      border-radius: 5px;
      cursor: pointer;
    }
  </style>
</head>
<body>
  <div class="dropdown">
    <button class="dropdown-btn">下拉菜单</button>
    <div class="dropdown-content">
      <a href="#">链接 1</a>
      <a href="#">链接 2</a>
      <a href="#">链接 3</a>
    </div>
  </div>
  <script>
    const dropdown = document.querySelector('.dropdown');
    const dropdownContent = document.querySelector('.dropdown-content');

    dropdown.addEventListener('mouseover', () => {
      dropdownContent.classList.add('show');
    });

    dropdown.addEventListener('mouseout', () => {
      dropdownContent.classList.remove('show');
    });
  </script>
</body>
</html>

手风琴效果

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>手风琴效果示例</title>
  <style>
    .accordion {
      margin: 20px 0;
    }
    .accordion-header {
      padding: 10px;
      background-color: #f1f1f1;
      cursor: pointer;
      display: flex;
      justify-content: space-between;
    }
    .accordion-content {
      padding: 0;
      max-height: 0;
      overflow: hidden;
      transition: max-height 0.3s ease-out;
    }
    .accordion-content.active {
      padding: 10px;
      max-height: 200px;
    }
    .arrow {
      transition: transform 0.3s ease;
    }
    .arrow.rotate {
      transform: rotate(180deg);
    }
  </style>
</head>
<body>
  <div class="accordion">
    <div class="accordion-header">
      <span>标题 1</span>
      <span class="arrow"></span>
    </div>
    <div class="accordion-content">
      <p>这是手风琴内容 1。</p>
    </div>
  </div>
  <div class="accordion">
    <div class="accordion-header">
      <span>标题 2</span>
      <span class="arrow"></span>
    </div>
    <div class="accordion-content">
      <p>这是手风琴内容 2。</p>
    </div>
  </div>
  <script>
    document.querySelectorAll('.accordion-header').forEach(header => {
      header.addEventListener('click', () => {
        const content = header.nextElementSibling;
        content.classList.toggle('active');
        header.querySelector('.arrow').classList.toggle('rotate');
      });
    });
  </script>
</body>
</html>

自定义右键菜单

        自定义右键菜单需要阻止默认的右键菜单,显示自定义的菜单,并根据点击位置定位。同时,点击页面其他位置时要隐藏菜单。这里可能需要动态创建菜单元素,并处理事件冒泡。

<div id="customMenu" style="display:none; position:absolute; background:#fff; box-shadow:0 0 5px #999">
  <div class="menu-item">复制</div>
  <div class="menu-item">粘贴</div>
  <div class="menu-item">刷新</div>
</div>

<script>
document.addEventListener('contextmenu', (e) => {
  e.preventDefault();
  const menu = document.getElementById('customMenu');
  menu.style.display = 'block';
  menu.style.left = e.pageX + 'px';
  menu.style.top = e.pageY + 'px';
});

document.addEventListener('click', () => {
  document.getElementById('customMenu').style.display = 'none';
});
</script>


二、表单处理类

表单验证增强

<form id="myForm">
  <input type="email" id="email" placeholder="邮箱">
  <div class="error" id="emailError"></div>
  
  <input type="password" id="password" placeholder="密码(6-12位)">
  <div class="error" id="pwdError"></div>

  <button type="submit">提交</button>
</form>

<script>
const form = document.getElementById('myForm');

// 实时验证
document.getElementById('email').addEventListener('input', (e) => {
  const email = e.target.value;
  const regex = /^[^\s@]+@[^\s@]+.[^\s@]+$/;
  document.getElementById('emailError').textContent = 
    regex.test(email) ? '' : '邮箱格式不正确';
});

// 提交验证
form.addEventListener('submit', (e) => {
  e.preventDefault();
  const pwd = document.getElementById('password').value;
  
  if(pwd.length < 6 || pwd.length > 12) {
    document.getElementById('pwdError').textContent = '密码长度需6-12位';
    return;
  }
  
  // 验证通过后提交
  form.submit();
});
</script>

密码强度检测(输入安全相关)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>密码强度检测示例</title>
  <style>
    #password {
      width: 100%;
      padding: 10px;
      margin-bottom: 20px;
    }
    #strengthMeter {
      width: 100%;
      height: 10px;
      background-color: #ddd;
      border-radius: 5px;
      margin-bottom: 10px;
    }
    #strengthMeterFill {
      height: 100%;
      width: 0;
      border-radius: 5px;
      transition: width 0.3s, background-color 0.3s;
    }
    #strengthText {
      font-size: 14px;
      color: #666;
    }
  </style>
</head>
<body>
  <input type="password" id="password" placeholder="输入密码">
  <div id="strengthMeter">
    <div id="strengthMeterFill"></div>
  </div>
  <div id="strengthText"></div>
  <script>
    document.getElementById('password').addEventListener('input', (e) => {
      const password = e.target.value;
      const meterFill = document.getElementById('strengthMeterFill');
      const strengthText = document.getElementById('strengthText');
      const strength = calculateStrength(password);
      meterFill.style.width = strength + '%';
      meterFill.style.backgroundColor = getStrengthColor(strength);
      strengthText.textContent = getStrengthText(strength);
    });

    function calculateStrength(password) {
      let strength = 0;
      if (password.length >= 8) strength += 25;
      if (/[A-Z]/.test(password)) strength += 25;
      if (/[a-z]/.test(password)) strength += 25;
      if (/[0-9]/.test(password)) strength += 25;
      return strength;
    }

    function getStrengthColor(strength) {
      if (strength < 25) return '#ff0000';
      if (strength < 50) return '#ffaa00';
      if (strength < 75) return '#ffdd00';
      return '#4CAF50';
    }

    function getStrengthText(strength) {
      if (strength < 25) return '弱';
      if (strength < 50) return '一般';
      if (strength < 75) return '强';
      return '非常强';
    }
  </script>
</body>
</html>


三、数据存储类

本地存储记忆功能(localStorage/cookie操作)

        本地存储记忆功能。这需要利用localStorage来保存用户的数据,比如表单输入或主题设置。在页面加载时读取存储的数据,并在数据变化时更新存储。例如,记住用户的搜索历史或表单填写内容。

// 保存数据
const saveData = () => {
  const data = {
    username: document.getElementById('name').value,
    theme: document.body.classList.contains('dark') ? 'dark' : 'light'
  };
  localStorage.setItem('userPrefs', JSON.stringify(data));
};

// 读取数据
window.addEventListener('load', () => {
  const saved = JSON.parse(localStorage.getItem('userPrefs'));
  if(saved) {
    document.getElementById('name').value = saved.username;
    if(saved.theme === 'dark') document.body.classList.add('dark');
  }
});

// 输入时自动保存
document.getElementById('name').addEventListener('input', saveData);


四、动态内容处理

实时搜索过滤

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>实时搜索过滤示例</title>
  <style>
    #searchInput {
      width: 100%;
      padding: 10px;
      margin-bottom: 20px;
    }
    .item {
      padding: 10px;
      margin-bottom: 5px;
      background-color: #f1f1f1;
    }
  </style>
</head>
<body>
  <input type="text" id="searchInput" placeholder="搜索...">
  <div class="item">项目 1</div>
  <div class="item">项目 2</div>
  <div class="item">项目 3</div>
  <div class="item">项目 4</div>
  <div class="item">项目 5</div>
  <script>
    document.getElementById('searchInput').addEventListener('input', (e) => {
      const searchTerm = e.target.value.toLowerCase();
      document.querySelectorAll('.item').forEach(item => {
        const text = item.textContent.toLowerCase();
        item.style.display = text.includes(searchTerm) ? 'block' : 'none';
      });
    });
  </script>
</body>
</html>

动态加载更多内容

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>动态加载更多内容示例</title>
  <style>
    #loadMore {
      padding: 10px 20px;
      background-color: #4CAF50;
      color: white;
      border: none;
      border-radius: 5px;
      cursor: pointer;
    }
    .item {
      padding: 10px;
      margin-bottom: 5px;
      background-color: #f1f1f1;
    }
  </style>
</head>
<body>
  <div id="content">
    <div class="item">项目 1</div>
    <div class="item">项目 2</div>
    <div class="item">项目 3</div>
  </div>
  <button id="loadMore">加载更多</button>
  <script>
    let currentPage = 1;
    const loadMoreBtn = document.getElementById('loadMore');

    loadMoreBtn.addEventListener('click', () => {
      currentPage++;
      // 模拟数据加载
      setTimeout(() => {
        const data = [`项目 ${currentPage * 3 - 2}`, `项目 ${currentPage * 3 - 1}`, `项目 ${currentPage * 3}`];
        renderItems(data);
      }, 1000);
    });

    function renderItems(data) {
      const content = document.getElementById('content');
      data.forEach(item => {
        const div = document.createElement('div');
        div.className = 'item';
        div.textContent = item;
        content.appendChild(div);
      });
    }
  </script>
</body>
</html>

随机名言生成器

        随机名言生成器需要预定义名言数组,随机选择一条显示,并可能通过按钮点击切换。如果用户需要,可以扩展为从API获取数据,但当前需求是纯JS,所以先使用本地数据。

<div id="quoteDisplay"></div>
<button onclick="newQuote()">新语录</button>

<script>
const quotes = [
  "代码写得好,头发掉得少",
  "Ctrl+C/V 是程序员最高礼仪",
  "程序不工作?试试console.log()",
  "永远相信:下一个版本会更好"
];

function newQuote() {
  const randomIndex = Math.floor(Math.random() * quotes.length);
  document.getElementById('quoteDisplay').textContent = quotes[randomIndex];
}

// 初始化
newQuote();
</script>


五、实用工具类

网页计时器/倒计时

        网页计时器/倒计时需要用到setInterval来更新时间显示,处理开始、暂停和重置功能。需要注意时间的格式化,如补零显示,并在倒计时结束时触发事件。

<div id="timer">00:00:00</div>
<button onclick="startTimer()">开始</button>
<button onclick="pauseTimer()">暂停</button>

<script>
let seconds = 0;
let timerId;

function formatTime(sec) {
  const h = Math.floor(sec/3600).toString().padStart(2,'0');
  const m = Math.floor(sec%3600/60).toString().padStart(2,'0');
  const s = (sec%60).toString().padStart(2,'0');
  return `${h}:${m}:${s}`;
}

function startTimer() {
  if(!timerId) {
    timerId = setInterval(() => {
      seconds++;
      document.getElementById('timer').textContent = formatTime(seconds);
    }, 1000);
  }
}

function pauseTimer() {
  clearInterval(timerId);
  timerId = null;
}
</script>

复制到剪贴板

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>复制到剪贴板示例</title>
  <style>
    #copyText {
      width: 100%;
      padding: 10px;
      margin-bottom: 20px;
      background-color: #f1f1f1;
    }
    #copyBtn {
      padding: 10px 20px;
      background-color: #4CAF50;
      color: white;
      border: none;
      border-radius: 5px;
      cursor: pointer;
    }
  </style>
</head>
<body>
  <div id="copyText">这是要复制的文本</div>
  <button id="copyBtn">复制到剪贴板</button>
  <script>
    document.getElementById('copyBtn').addEventListener('click', () => {
      const text = document.getElementById('copyText').innerText;
      navigator.clipboard.writeText(text)
        .then(() => {
          alert('已复制!');
        })
        .catch(err => {
          console.error('复制失败:', err);
          // 降级方案
          const textarea = document.createElement('textarea');
          textarea.value = text;
          document.body.appendChild(textarea);
          textarea.select();
          document.execCommand('copy');
          document.body.removeChild(textarea);
          alert('已复制!');
        });
    });
  </script>
</body>
</html>

简易画板功能(图形交互工具)

        简易画板功能需要处理canvas的鼠标事件,跟踪鼠标位置来绘制路径。可能需要设置画笔属性,如颜色和粗细,并实现清除画布的功能。

<canvas id="myCanvas" width="500" height="300"></canvas>
<button onclick="clearCanvas()">清空</button>

<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
let isDrawing = false;

canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);

function startDrawing(e) {
  isDrawing = true;
  ctx.beginPath();
  ctx.moveTo(e.offsetX, e.offsetY);
}

function draw(e) {
  if(!isDrawing) return;
  ctx.lineTo(e.offsetX, e.offsetY);
  ctx.stroke();
}

function stopDrawing() {
  isDrawing = false;
}

function clearCanvas() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
}
</script>


六、用户体验优化

回到顶部按钮

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>回到顶部按钮示例</title>
  <style>
    body {
      height: 2000px;
    }
    #topBtn {
      position: fixed;
      bottom: 20px;
      right: 20px;
      display: none;
      width: 50px;
      height: 50px;
      background-color: #4CAF50;
      color: white;
      border-radius: 50%;
      text-align: center;
      line-height: 50px;
      cursor: pointer;
    }
  </style>
</head>
<body>
  <div style="height: 1500px; background-color: #f1f1f1;"></div>
  <button id="topBtn"></button>
  <script>
    window.onscroll = () => {
      document.getElementById('topBtn').style.display = 
        (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) ? 'block' : 'none';
    };

    document.getElementById('topBtn').onclick = () => {
      window.scrollTo({
        top: 0,
        behavior: 'smooth'
      });
    };

    window.onload = () => {
      document.getElementById('topBtn').style.display = 'none';
    };
  </script>
</body>
</html>

图片懒加载(性能优化)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>图片懒加载示例</title>
  <style>
    .lazyload {
      width: 100%;
      height: 200px;
      background-color: #f1f1f1;
      margin: 20px 0;
    }
  </style>
</head>
<body>
  <img data-src="https://via.placeholder.com/800x200" class="lazyload" alt="Lazy-loaded image">
  <img data-src="https://via.placeholder.com/800x200" class="lazyload" alt="Lazy-loaded image">
  <img data-src="https://via.placeholder.com/800x200" class="lazyload" alt="Lazy-loaded image">
  <div style="height: 1000px;"></div>
  <script>
    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          const img = entry.target;
          img.src = img.dataset.src;
          observer.unobserve(img);
        }
      });
    });

    document.querySelectorAll('.lazyload').forEach(img => observer.observe(img));
  </script>
</body>
</html>

原生js图片放大镜效果

        图片放大镜效果比较复杂。需要监听鼠标移动事件,计算放大区域的位置和比例,使用canvas来绘制放大后的图像。可能需要处理图片的加载和缩放比例,确保放大镜跟随鼠标移动。

<div class="img-container">
  <img src="small.jpg" id="targetImg">
  <div id="magnifier" style="display:none; width:200px; height:200px; position:absolute"></div>
</div>

<script>
const img = document.getElementById('targetImg');
const magnifier = document.getElementById('magnifier');

img.addEventListener('mousemove', (e) => {
  const rect = img.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;
  
  magnifier.style.display = 'block';
  magnifier.style.background = `
    url(${img.src}) 
    no-repeat 
    ${-x*2}px ${-y*2}px
  `;
  magnifier.style.left = e.pageX + 15 + 'px';
  magnifier.style.top = e.pageY + 15 + 'px';
});

img.addEventListener('mouseleave', () => {
  magnifier.style.display = 'none';
});
</script>

暗黑模式切换

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>暗黑模式切换示例</title>
  <style>
    body {
      transition: background-color 0.3s, color 0.3s;
    }
    body.dark-mode {
      background-color: #333;
      color: white;
    }
    #darkModeToggle {
      padding: 10px 20px;
      background-color: #4CAF50;
      color: white;
      border: none;
      border-radius: 5px;
      cursor: pointer;
    }
  </style>
</head>
<body>
  <button id="darkModeToggle">切换暗黑模式</button>
  <script>
    const toggle = document.getElementById('darkModeToggle');

    toggle.addEventListener('click', () => {
      document.body.classList.toggle('dark-mode');
      const theme = document.body.classList.contains('dark-mode') ? 'dark' : 'light';
      localStorage.setItem('theme', theme);
    });

    window.onload = () => {
      const savedTheme = localStorage.getItem('theme');
      if (savedTheme === 'dark') {
        document.body.classList.add('dark-mode');
      }
    };
  </script>
</body>
</html>

网页主题色切换

        网页主题色切换可以通过切换CSS类或直接修改样式属性,使用localStorage记住用户选择的主题。需要考虑如何动态改变主题颜色,并在页面加载时应用已保存的主题。

<button onclick="toggleTheme()">切换主题</button>

<script>
function toggleTheme() {
  const root = document.documentElement;
  const isDark = root.classList.toggle('dark-theme');
  
  // 保存主题状态
  localStorage.setItem('theme', isDark ? 'dark' : 'light');
}

// 初始化主题
document.addEventListener('DOMContentLoaded', () => {
  const savedTheme = localStorage.getItem('theme') || 'light';
  document.documentElement.classList.toggle('dark-theme', savedTheme === 'dark');
});

/* CSS需配合:
:root { --bg: #fff; --text: #333; }
.dark-theme { --bg: #222; --text: #fff; }
body { background: var(--bg); color: var(--text); }
*/
</script>


七、视觉效果类

点击切换图片(基础视觉交互)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>产品展示/图片画廊</title>
<style>
    * {
        margin: 0;
        padding: 0;
    }
    .nav {
        width: 80%;
        margin: 0 auto;
        height: 65px;
        display: flex;
    }
    .nav span {
        flex: 1;
        height: 65px;
        text-align: center;
        line-height: 65px;
        font-size: 24px;
        font-weight: bold;
        cursor: pointer; /* 添加鼠标指针样式 */
    }
    .nav .siz {
        background: orange; /* 高亮显示的导航项背景色 */
    }
    .content {
        width: 80%;
        height: 500px;
        margin: 20px auto; /* 调整内容与导航之间的间距 */
        display: flex;
        flex-wrap: wrap; /* 允许内容换行 */
    }
    .content div {
        display: none; /* 默认隐藏所有内容区域 */
        width: 49%; /* 设置每个内容区域的宽度 */
        margin: 0.5%; /* 设置内容区域之间的间距 */
        box-sizing: border-box; /* 包含内边距和边框在内计算元素的总宽度和高度 */
    }
    .content .show {
        display: block; /* 显示当前高亮的内容区域 */
    }
    .content img {
        width: 100%; /* 图片宽度自适应内容区域 */
        height: auto; /* 图片高度自动调整以保持比例 */
    }
</style>
</head>
<body>

<div class="nav"></div>
<div class="content"></div>

<script>
    let car = {
        data: [
            { name: '产品1', pics: ['img1-1.jpg', 'img1-2.jpg'] },
            { name: '产品2', pics: ['img2-1.jpg', 'img2-2.jpg'] },
            // ... 可以继续添加更多产品数据
        ]
    };

    let data = car.data;
    let nav = document.querySelector(".nav");
    let content = document.querySelector(".content");

    // 渲染导航和内容区域
    for (let i = 0; i < data.length; i++) {
        let span = document.createElement("span");
        span.innerText = data[i].name;
        span.onclick = function () {
            // 移除所有span和div的siz和show类
            let navSpans = document.querySelectorAll(".nav span");
            let contentDivs = document.querySelectorAll(".content div");
            navSpans.forEach(span => span.className = '');
            contentDivs.forEach(div => div.className = '');

            // 给当前点击的span和对应的div添加siz和show类
            this.className = 'siz';
            contentDivs[i].className = 'show';
        }
        nav.appendChild(span);

        let div = document.createElement("div");
        let img1 = document.createElement("img");
        let img2 = document.createElement("img"); 
        // 这里虽然创建了两个img元素,但实际上每个div只显示一个(根据需求调整)
        // 为了简化示例,这里只设置第一个img的src,第二个可以隐藏或根据需求处理
        img1.setAttribute("src", data[i].pics[0]);
        // img2.setAttribute("src", data[i].pics[1]); 
        // 如果需要显示两张图片,可以取消注释并调整CSS布局
        div.appendChild(img1);
        // div.appendChild(img2); 
        // 如果需要显示两张图片,可以取消注释
        content.appendChild(div);
    }

    // 设置初始状态:默认显示第一个产品/项目
    let navSpans = document.querySelectorAll(".nav span");
    let contentDivs = document.querySelectorAll(".content div");
    if (navSpans.length > 0 && contentDivs.length > 0) {
        navSpans[0].className = 'siz';
        contentDivs[0].className = 'show';
    }
</script>

</body>
</html>

滚动动画触发

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>滚动动画触发示例</title>
  <style>
    .animate-on-scroll {
      opacity: 0;
      transform: translateY(20px);
      transition: opacity 0.5s, transform 0.5s;
    }
    .animate-on-scroll.active {
      opacity: 1;
      transform: translateY(0);
    }
    .box {
      width: 100%;
      height: 200px;
      background-color: #f1f1f1;
      margin: 20px 0;
      padding: 20px;
      box-sizing: border-box;
    }
    .spacer {
      height: 1000px;
      background-color: #f9f9f9;
    }
  </style>
</head>
<body>
  <div class="spacer"></div>
  <div class="animate-on-scroll box">动画内容 1</div>
  <div class="animate-on-scroll box">动画内容 2</div>
  <div class="animate-on-scroll box">动画内容 3</div>
  <div class="spacer"></div>
  <script>
    window.addEventListener('scroll', () => {
      document.querySelectorAll('.animate-on-scroll').forEach(el => {
        const rect = el.getBoundingClientRect();
        if (rect.top < window.innerHeight * 0.8) {
          el.classList.add('active');
        }
      });
    });
  </script>
</body>
</html>

视差滚动效果

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>视差滚动效果示例</title>
  <style>
    .parallax {
      position: relative;
      height: 500px;
      background-image: url('https://via.placeholder.com/1920x1080');
      background-size: cover;
      background-position: center;
    }
    .content {
      height: 1000px;
      background-color: #f1f1f1;
      padding: 20px;
    }
  </style>
</head>
<body>
  <div class="parallax"></div>
  <div class="content">
    <p>滚动页面查看视差效果。</p>
    <!-- 添加更多内容 -->
  </div>
  <script>
    window.addEventListener('scroll', () => {
      const scrolled = window.pageYOffset;
      document.querySelector('.parallax').style.transform = `translateY(${scrolled * 0.5}px)`;
    });
  </script>
</body>
</html>

此文尚需更新,敬请期待

码字不易,各位大佬点点赞呗