当然可以!我来给你一个完整的思路和示例,教你用 HTML + JavaScript 实现一个 滑动验证码。我会把重点讲清楚,同时给出可运行的示例。


1️⃣ 滑动验证码原理

滑动验证码通常包含以下几个部分:

  1. 背景图:有一块缺口的完整图片。
  2. 滑块:用户拖动滑块去填补缺口。
  3. 验证逻辑:判断滑块是否与缺口对齐。

核心原理是:

  • 在原图上随机生成一个缺口位置。
  • 用户拖动滑块到对应位置。
  • 判断滑块的最终位置是否与缺口重合(允许一定误差)。

2️⃣ HTML结构

<div class="captcha-container">
  <canvas id="captchaCanvas" width="310" height="155"></canvas>
  <div class="slider-container">
    <div id="slider" class="slider">⬜</div>
  </div>
</div>
<p id="result"></p>

说明:

  • canvas 用来绘制背景图和缺口。
  • slider 是可以拖动的滑块。
  • result 显示验证结果。

3️⃣ CSS样式

.captcha-container {
  position: relative;
  width: 310px;
}

.slider-container {
  width: 310px;
  height: 40px;
  background: #eee;
  border-radius: 20px;
  margin-top: 10px;
  position: relative;
}

.slider {
  width: 40px;
  height: 40px;
  background: #ccc;
  border-radius: 50%;
  position: absolute;
  left: 0;
  top: 0;
  cursor: pointer;
  text-align: center;
  line-height: 40px;
  font-size: 24px;
  user-select: none;
}


4️⃣ JavaScript逻辑

const canvas = document.getElementById('captchaCanvas');
const ctx = canvas.getContext('2d');
const slider = document.getElementById('slider');
const result = document.getElementById('result');

const canvasWidth = canvas.width;
const canvasHeight = canvas.height;

let blockX = 0; // 缺口的X坐标
const blockSize = 50; // 缺口宽度
const tolerance = 5; // 误差范围

// 1. 绘制背景和缺口
function drawCaptcha() {
  // 随机缺口位置
  blockX = Math.floor(Math.random() * (canvasWidth - blockSize - 20)) + 10;

  // 背景
  ctx.fillStyle = '#c0c0c0';
  ctx.fillRect(0, 0, canvasWidth, canvasHeight);

  // 缺口
  ctx.fillStyle = '#fff';
  ctx.fillRect(blockX, 55, blockSize, blockSize);
}

drawCaptcha();

// 2. 滑块拖动逻辑
let isDragging = false;
let startX = 0;

slider.addEventListener('mousedown', function(e) {
  isDragging = true;
  startX = e.clientX - slider.offsetLeft;
});

document.addEventListener('mousemove', function(e) {
  if (!isDragging) return;
  let moveX = e.clientX - startX;

  // 限制滑块范围
  moveX = Math.max(0, Math.min(moveX, canvasWidth - slider.offsetWidth));
  slider.style.left = moveX + 'px';
});

document.addEventListener('mouseup', function(e) {
  if (!isDragging) return;
  isDragging = false;

  const finalX = parseInt(slider.style.left);

  if (Math.abs(finalX - blockX) <= tolerance) {
    result.textContent = '✅ 验证通过';
  } else {
    result.textContent = '❌ 验证失败,请重试';
    slider.style.left = '0px';
    drawCaptcha();
  }
});


5️⃣ 功能说明

  • 随机缺口:每次刷新或验证失败后都会生成新的缺口。
  • 滑块拖动:拖动滑块时位置受限,防止超出范围。
  • 误差判断:允许 ±5px 误差,用户体验更好。

6️⃣ 可优化点

  1. 使用真实图片代替纯色背景,更难被机器人识别。
  2. 缺口形状可以是拼图样式,更安全。
  3. 移动端触控支持:用 touchstarttouchmovetouchend
  4. 后端验证:将缺口位置和滑块位置发送到后端验证,防止被绕过。