在网页开发中,JavaScript 发挥着至关重要的作用,为网页带来丰富的交互性和动态效果,极大地提升了用户体验。本文将通过几个具体案例展示 JavaScript 的强大魅力。

一、美丽的画布时钟

这是一个使用 JavaScript 在网页上创建美丽画布时钟的案例。通过 HTML 的canvas元素,结合 CSS 进行样式设置,再利用 JavaScript 进行图形绘制和时间更新,实现了一个实时显示的时钟效果。

首先,在 HTML 中定义了一个canvas元素,并设置了宽度和高度。在 CSS 中,对canvas进行了一些基本的样式设置,如背景颜色、边框和阴影等,使其在页面中更加突出。

在 JavaScript 部分,首先获取canvas元素并获取其上下文,以便进行图形绘制。然后,通过一系列的数学计算,将当前时间转换为角度,用于绘制时钟的指针和刻度。使用setInterval方法每秒触发一次绘制时钟的函数,保证时钟的实时性。在绘制过程中,使用不同的线条样式和颜色,绘制了时钟的外圆、中心圆、指针、刻度和数字等元素,最终呈现出一个美观的时钟效果。

以下是完整代码示例:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Beautiful Canvas Clock with Carousel</title>
  <style>
    body {
      margin: 0;
      padding: 0;
      background-color: white;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
    }
    canvas {
      background-color: white;
      border: 10px solid #d3d3d3;
      box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
      position: relative;
    }
  </style>
</head>

<body>
  <canvas id="clockCanvas" width="400" height="400"></canvas>

  <script>
    const canvas = document.getElementById('clockCanvas');
    const ctx = canvas.getContext('2d');
    const borderWidth = 10;
    const adjustedWidth = canvas.width - borderWidth * 2;
    const adjustedHeight = canvas.height - borderWidth * 2;
    const outerRadius = Math.min(adjustedWidth, adjustedHeight) / 2 - 5; 

    function drawClock() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // 绘制完整的外圆
      ctx.beginPath();
      ctx.arc(outerRadius + borderWidth, outerRadius + borderWidth, outerRadius, 0, 2 * Math.PI);
      ctx.strokeStyle = '#888';
      ctx.lineWidth = 12;
      ctx.stroke();

      // 绘制时钟中心圆
      ctx.beginPath();
      ctx.arc(outerRadius + borderWidth, outerRadius + borderWidth, 10, 0, 2 * Math.PI);
      ctx.fillStyle = 'goldenrod';
      ctx.fill();

      const now = new Date();
      const hours = now.getHours();
      const minutes = now.getMinutes();
      const seconds = now.getSeconds();

      const hourAngle = ((hours % 12) + minutes / 60 + seconds / 3600) * (2 * Math.PI / 12);
      const minuteAngle = ((minutes + seconds / 60) * (2 * Math.PI / 60));
      const secondAngle = (seconds * (2 * Math.PI / 60));

      // 绘制时针
      drawHand(hourAngle, outerRadius * 0.4, 12, 'navy', 'rgba(0, 0, 128, 0.5)');

      // 绘制分针
      drawHand(minuteAngle, outerRadius * 0.7, 6, 'gray', 'rgba(180, 180, 180, 0.5)');

      // 绘制秒针
      drawHand(secondAngle, outerRadius * 0.9, 2, 'crimson', 'rgba(255, 0, 0, 0.3)');

      // 绘制小时刻度
      for (let i = 0; i < 12; i++) {
        const angle = (i / 12) * 2 * Math.PI;
        ctx.beginPath();
        ctx.lineWidth = 8;
        ctx.strokeStyle = '#888';
        ctx.moveTo((outerRadius + borderWidth) + Math.sin(angle) * (outerRadius - 35), (outerRadius + borderWidth) - Math.cos(angle) * (outerRadius - 35));
        ctx.lineTo((outerRadius + borderWidth) + Math.sin(angle) * (outerRadius - 45), (outerRadius + borderWidth) - Math.cos(angle) * (outerRadius - 45));
        ctx.stroke();
      }

      // 绘制分钟刻度
      for (let i = 0; i < 60; i++) {
        if (i % 5!== 0) {
          const angle = (i / 60) * 2 * Math.PI;
          ctx.beginPath();
          ctx.lineWidth = 3;
          ctx.strokeStyle = 'lightgray';
          ctx.moveTo((outerRadius + borderWidth) + Math.sin(angle) * (outerRadius - 30), (outerRadius + borderWidth) - Math.cos(angle) * (outerRadius - 30));
          ctx.lineTo((outerRadius + borderWidth) + Math.sin(angle) * (outerRadius - 33), (outerRadius + borderWidth) - Math.cos(angle) * (outerRadius - 33));
          ctx.stroke();
        }
      }

      // 绘制数字
      ctx.font = "24px Arial";
      ctx.textAlign = "center";
      ctx.textBaseline = "middle";
      ctx.fillStyle = '#888';
      for (let i = 1; i <= 12; i++) {
        const angle = (i / 12) * 2 * Math.PI;
        const x = (outerRadius + borderWidth) + Math.sin(angle) * (outerRadius - 65);
        const y = (outerRadius + borderWidth) - Math.cos(angle) * (outerRadius - 65);
        ctx.fillText(i.toString(), x, y);
      }
    }

    function drawHand(angle, length, width, color, gradientColor) {
      ctx.beginPath();
      ctx.lineWidth = width;
      ctx.strokeStyle = color;
      ctx.moveTo(outerRadius + borderWidth, outerRadius + borderWidth);
      ctx.lineTo((outerRadius + borderWidth) + Math.sin(angle) * length, (outerRadius + borderWidth) - Math.cos(angle) * length);
      ctx.stroke();

      // 添加渐变效果
      const gradient = ctx.createLinearGradient(outerRadius + borderWidth, outerRadius + borderWidth, (outerRadius + borderWidth) + Math.sin(angle) * length, (outerRadius + borderWidth) - Math.cos(angle) * length);
      gradient.addColorStop(0, gradientColor);
      gradient.addColorStop(1, color);
      ctx.strokeStyle = gradient;
      ctx.lineWidth = width + 2;
      ctx.beginPath();
      ctx.moveTo(outerRadius + borderWidth, outerRadius + borderWidth);
      ctx.lineTo((outerRadius + borderWidth) + Math.sin(angle) * length, (outerRadius + borderWidth) - Math.cos(angle) * length);
      ctx.stroke();
    }

    setInterval(drawClock, 1000);
  </script>
</body>

</html>

二、自动轮播图

这个案例展示了一个带有上一张和下一张按钮的自动轮播图。通过 HTML、CSS 和 JavaScript 的结合,实现了图片的自动切换和手动控制切换的功能。

在 HTML 中,定义了一个包含图片的容器div和两个按钮,用于切换图片。在 CSS 中,设置了容器和图片的样式,以及按钮的样式,使其在页面中呈现出美观的效果。

在 JavaScript 部分,首先通过querySelectorAll方法获取所有的图片元素,并设置一个变量来记录当前显示的图片索引。定义了三个函数,分别用于显示指定索引的图片、切换到下一张图片和切换到上一张图片。为 “下一张” 和 “上一张” 按钮添加了点击事件监听器,分别调用对应的切换图片函数。同时,使用setInterval方法定时触发切换到下一张图片的函数,实现自动轮播的效果。

以下是完整代码示例:

<!DOCTYPE html>
<html lang="en">
 
<head>
  <meta charset="UTF-8">
  <style>
.carousel {
      position: relative;
      width: 500px;
      height: 300px;
      overflow: hidden;
    }
 
.carousel img {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      opacity: 0;
      transition: opacity 0.5s ease;
    }
 
.carousel img.active {
      opacity: 1;
    }
 
.controls {
      text-align: center;
      width: 500px;
      margin-top: 10px;
    }
 
    button {
      background-color: #4CAF50;
      color: white;
      padding: 10px 20px;
      border: none;
      cursor: pointer;
      border-radius: 5px;
      transition: background-color 0.3s ease;
    }
 
    button:hover {
      background-color: #45a049;
    }
  </style>
</head>
 
<body>
  <div class="carousel">
    <img src="https://img-blog.csdnimg.cn/166e183e84094c44bbc8ad66500cef5b.jpeg#pic_center" alt="Image 1" class="active">
    <img src="https://i0.hdslb.com/bfs/archive/17104a320fa20171d79f1498341047d9c6dfc5c4.jpg" alt="Image 2">
    <img src="https://k.sinaimg.cn/n/sinakd10116/89/w1080h609/20240523/df1f-41ed22b9c30a12e231909f7756ef4ced.png/w700d1q75cms.jpg?by=cms_fixed_width" alt="Image 3">
  </div>
  <div class="controls">
    <button id="prevButton">上一张</button>
    <button id="nextButton">下一张</button>
  </div>
 
  <script>
    const images = document.querySelectorAll('.carousel img');
    let currentIndex = 0;
 
    function showImage(index) {
      images.forEach((image, i) => {
        if (i === index) {
          image.classList.add('active');
          image.style.opacity = 1;
        } else {
          image.classList.remove('active');
          image.style.opacity = 0;
        }
      });
    }
 
    function nextImage() {
      currentIndex++;
      if (currentIndex >= images.length) {
        currentIndex = 0;
      }
      showImage(currentIndex);
    }
 
    function prevImage() {
      currentIndex--;
      if (currentIndex < 0) {
        currentIndex = images.length - 1;
      }
      showImage(currentIndex);
    }
 
    document.getElementById('nextButton').addEventListener('click', nextImage);
    document.getElementById('prevButton').addEventListener('click', prevImage);
 
    setInterval(nextImage, 3000);
  </script>
</body>
 
</html>

三、表单验证

这个案例实现了一个简单的表单验证功能。通过 JavaScript 对用户在表单中输入的数据进行检查,确保数据的有效性。

在 HTML 中,定义了一个包含用户名、邮箱和密码输入框以及提交按钮的表单。在 CSS 中,设置了输入框在错误状态下的样式,以便在用户输入错误时进行提示。

在 JavaScript 部分,首先通过querySelector方法获取表单元素以及各个输入框元素。为表单添加提交事件监听器,在提交事件处理函数中,检查各个输入框的值是否为空或是否符合特定格式(如邮箱格式验证)。如果输入不符合要求,为输入框添加错误样式,提示用户输入有误。如果输入有效,则可以进行提交表单或其他操作。

以下是完整代码示例:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <style>
    input.error {
      border: 1px solid red;
    }
  </style>
</head>

<body>
  <form>
    <input type="text" name="username" placeholder="用户名">
    <input type="email" name="email" placeholder="邮箱">
    <input type="password" name="password" placeholder="密码">
    <input type="submit" value="提交">
  </form>

  <script>
    const form = document.querySelector('form');
    const usernameInput = document.querySelector('input[name="username"]');
    const emailInput = document.querySelector('input[name="email"]');
    const passwordInput = document.querySelector('input[name="password"]');

    form.addEventListener('submit', function(event) {
      event.preventDefault();

      let isValid = true;

      if (usernameInput.value === '') {
        isValid = false;
        usernameInput.classList.add('error');
      } else {
        usernameInput.classList.remove('error');
      }

      if (emailInput.value === '' ||!isValidEmail(emailInput.value)) {
        isValid = false;
        emailInput.classList.add('error');
      } else {
        emailInput.classList.remove('error');
      }

      if (passwordInput.value === '') {
        isValid = false;
        passwordInput.classList.add('error');
      } else {
        passwordInput.classList.remove('error');
      }

      if (isValid) {
        // 表单数据有效,可以提交
        alert('表单提交成功!');
      }
    });

    function isValidEmail(email) {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      return emailRegex.test(email);
    }
  </script>
</body>

</html>

四、可拖动的小 div 在大 div 内

这个案例实现了一个可在大div内拖动的小div。通过 JavaScript 监听鼠标事件,实现小div的拖动效果,并确保小div始终在大div的范围内。

在 HTML 中,定义了一个大div和一个小div。在 CSS 中,设置了大div和小div的样式,使其在页面中呈现出明显的区别。

在 JavaScript 部分,首先获取大div和小div元素。为小div添加鼠标按下事件监听器,在鼠标按下时,记录鼠标位置与小div位置的差值。为文档添加鼠标移动事件监听器,当鼠标移动且处于拖动状态时,根据鼠标位置和记录的差值计算小div的新位置,并进行边界限制,确保小div始终在大div内部。为文档添加鼠标松开事件监听器,停止拖动状态。

以下是完整代码示例:

<!DOCTYPE html>
<html lang="en">

<head>
  <style>
.big-div {
      width: 300px;
      height: 300px;
      border: 2px solid black;
      position: relative;
    }

.small-div {
      width: 50px;
      height: 50px;
      background-color: blue;
      position: absolute;
    }
  </style>
</head>

<body>
  <div class="big-div">
    <div class="small-div"></div>
  </div>

  <script>
    const smallDiv = document.querySelector('.small-div');
    const bigDiv = document.querySelector('.big-div');

    let isDragging = false;
    let offsetX, offsetY;

    smallDiv.addEventListener('mousedown', function(event) {
      isDragging = true;
      offsetX = event.clientX - smallDiv.offsetLeft;
      offsetY = event.clientY - smallDiv.offsetTop;
    });

    document.addEventListener('mousemove', function(event) {
      if (isDragging) {
        let newLeft = event.clientX - offsetX;
        let newTop = event.clientY - offsetY;

        // 限制在大 div 内
        if (newLeft < 0) newLeft = 0;
        if (newTop < 0) newTop = 0;
        if (newLeft > bigDiv.offsetWidth - smallDiv.offsetWidth) newLeft = bigDiv.offsetWidth - smallDiv.offsetWidth;
        if (newTop > bigDiv.offsetHeight - smallDiv.offsetHeight) newTop = bigDiv.offsetHeight - smallDiv.offsetHeight;

        smallDiv.style.left = newLeft + 'px';
        smallDiv.style.top = newTop + 'px';
      }
    });

    document.addEventListener('mouseup', function() {
      isDragging = false;
    });
  </script>
</body>

</html>

结论

本文通过四个案例展示了 JavaScript 在网页设计中的强大作用。包括美丽的画布时钟、自动轮播图、表单验证以及可拖动的小 div。这些案例体现了 JavaScript 在图形绘制、元素操作、事件处理和数据验证等方面的能力,极大地提升了网页的交互性和用户体验,凸显了 JavaScript 在网页设计中的不可或缺性。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部