html+jQuery如何实现拖动滑块图片拼图验证码插件

小编给大家分享一下html+jQuery如何实现拖动滑块图片拼图验证码插件,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

电脑和手机移动端都适用的jQuery拖动滑块图片拼图验证码插件,通过鼠标拖动或触屏滑动填充拼图来进行安全验证,点击刷新可以更换当前待验证的图片。

HTML & css:

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>拖动滑块图片拼图验证码插件</title>
<!--框架样式-->
<link href="css/bootstrap.min.css" rel="external nofollow" rel="stylesheet">
<!--图标样式-->
<link href="https://cdn.bootcss.com/font-awesome/5.7.2/css/all.min.css" rel="stylesheet">
<!--主要样式-->
<link href="disk/slidercaptcha.css" rel="external nofollow" rel="stylesheet" />
<style>
.slidercaptcha {
 margin: 0 auto;
 width: 314px;
 height: 286px;
 border-radius: 4px;
 box-shadow: 0 0 10px rgba0, 0, 0, 0.125);
 margin-top: 40px;
}
.slidercaptcha .card-body {
 padding: 1rem;
}
.slidercaptcha canvas:first-child {
 border-radius: 4px;
 border: 1px solid #e6e8eb;
}
.slidercaptcha.card .card-header {
 background-image: none;
 background-color: rgba0, 0, 0, 0.03);
}
.refreshIcon {
 top: -54px;
}
</style>
</head>
<body>
<div class="container-fluid">
 <div class="form-row">
 <div class="col-12">
 <div class="slidercaptcha card">
 <div class="card-header">
  <span>请完成安全验证</span>
 </div>
 <div class="card-body"><div id="captcha"></div></div>
 </div>
 </div>
 </div>
</div>
<script src="js/jquery-1.11.0.min.js" type="text/javascript"></script>
<script src="disk/longbow.slidercaptcha.js"></script>
<script>
 $'#captcha').sliderCaptcha{
 repeatIcon: 'fa fa-redo',
 setSrc: function ) {
 return 'https://cache.yisu.com/upload/information/20200622/114/14881.jpg';
 },
 onSuccess: function ) {
 alert'验证通过!');
 }
 });
</script>
</body>
</html>
disk/slidercaptcha.css:
body {
 overflow-x: hidden;
}
.block {
 position: absolute;
 left: 0;
 top: 0;
}
.sliderContainer {
 position: relative;
 text-align: center;
 line-height: 40px;
 background: #f7f9fa;
 color: #45494c;
 border-radius: 2px;
}
.sliderbg {
 position: absolute;
 left: 0;
 right: 0;
 top: 0;
 background-color: #f7f9fa;
 height: 40px;
 border-radius: 2px;
 border: 1px solid #e6e8eb;
}
.sliderContainer_active .slider {
 top: -1px;
 border: 1px solid #1991FA;
}
.sliderContainer_active .sliderMask {
 border-width: 1px 0 1px 1px;
}
.sliderContainer_success .slider {
 top: -1px;
 border: 1px solid #52CCBA;
 background-color: #52CCBA !important;
}
.sliderContainer_success .sliderMask {
 border: 1px solid #52CCBA;
 border-width: 1px 0 1px 1px;
 background-color: #D2F4EF;
}
.sliderContainer_success .sliderIcon:before {
 content: "\f00c";
}
.sliderContainer_fail .slider {
 top: -1px;
 border: 1px solid #f57a7a;
 background-color: #f57a7a !important;
}
.sliderContainer_fail .sliderMask {
 border: 1px solid #f57a7a;
 background-color: #fce1e1;
 border-width: 1px 0 1px 1px;
}
.sliderContainer_fail .sliderIcon:before {
 content: "\f00d";
}
.sliderContainer_active .sliderText, .sliderContainer_success .sliderText, .sliderContainer_fail .sliderText {
 display: none;
}
.sliderMask {
 position: absolute;
 left: 0;
 top: 0;
 height: 40px;
 border: 0 solid #1991FA;
 background: #D1E9FE;
 border-radius: 2px;
}
.slider {
 position: absolute;
 top: 0;
 left: 0;
 width: 40px;
 height: 40px;
 background: #fff;
 box-shadow: 0 0 3px rgba0, 0, 0, 0.3);
 cursor: pointer;
 transition: background .2s linear;
 border-radius: 2px;
 display: flex;
 align-items: center;
 justify-content: center;
}
.slider:hover {
 background: #1991FA;
}
.slider:hover .sliderIcon {
 background-position: 0 -13px;
}
.sliderText {
 position: relative;
}
.sliderIcon {
}
.refreshIcon {
 position: absolute;
 right: 0;
 top: 0;
 cursor: pointer;
 margin: 6px;
 color: rgba0,0,0,.25);
 font-size: 1rem;
 z-index: 5;
 transition: color .3s linear;
}
 .refreshIcon:hover {
 color: #6c757d;
 }
disk/longbow.slidercaptcha.js:
function $) {
 'use strict';
 var SliderCaptcha = function element, options) {
  this.$element = $element);
  this.options = $.extend{}, SliderCaptcha.DEFAULTS, options);
  this.$element.css{ 'position': 'relative', 'width': this.options.width + 'px', 'margin': '0 auto' });
  this.init);
 };
 SliderCaptcha.VERSION = '1.0';
 SliderCaptcha.Author = 'argo@163.com';
 SliderCaptcha.DEFAULTS = {
  width: 280,  // canvas宽度
  height: 155, // canvas高度
  PI: Math.PI,
  sliderL: 42, // 滑块边长
  sliderR: 9,  // 滑块半径
  offset: 5,  // 容错偏差
  loadingText: '正在加载中...',
  failedText: '再试一次',
  barText: '向右滑动填充拼图',
  repeatIcon: 'fa fa-repeat',
  maxLoadCount: 3,
  localImages: function ) {
   return 'images/Pic' + Math.roundMath.random) * 4) + '.jpg';
  }
 };
 function Pluginoption) {
  return this.eachfunction ) {
   var $this = $this);
   var data = $this.data'lgb.SliderCaptcha');
   var options = typeof option === 'object' && option;
   if data && !/reset/.testoption)) return;
   if !data) $this.data'lgb.SliderCaptcha', data = new SliderCaptchathis, options));
   if typeof option === 'string') data[option]);
  });
 }
 $.fn.sliderCaptcha = Plugin;
 $.fn.sliderCaptcha.Constructor = SliderCaptcha;
 var _proto = SliderCaptcha.prototype;
 _proto.init = function ) {
  this.initDOM);
  this.initImg);
  this.bindEvents);
 };
 _proto.initDOM = function ) {
  var createElement = function tagName, className) {
   var elment = document.createElementtagName);
   elment.className = className;
   return elment;
  };
  var createCanvas = function width, height) {
   var canvas = document.createElement'canvas');
   canvas.width = width;
   canvas.height = height;
   return canvas;
  };
  var canvas = createCanvasthis.options.width - 2, this.options.height) // 画布
  var block = canvas.cloneNodetrue) // 滑块
  var sliderContainer = createElement'div', 'sliderContainer');
  var refreshIcon = createElement'i', 'refreshIcon ' + this.options.repeatIcon);
  var sliderMask = createElement'div', 'sliderMask');
  var sliderbg = createElement'div', 'sliderbg');
  var slider = createElement'div', 'slider');
  var sliderIcon = createElement'i', 'fa fa-arrow-right sliderIcon');
  var text = createElement'span', 'sliderText');
  block.className = 'block'
  text.innerHTML = this.options.barText;
  var el = this.$element;
  el.append$canvas));
  el.append$refreshIcon));
  el.append$block));
  slider.appendChildsliderIcon);
  sliderMask.appendChildslider);
  sliderContainer.appendChildsliderbg);
  sliderContainer.appendChildsliderMask);
  sliderContainer.appendChildtext);
  el.append$sliderContainer));
  Object.assignthis, {
   canvas,
   block,
   sliderContainer: $sliderContainer),
   refreshIcon,
   slider,
   sliderMask,
   sliderIcon,
   text: $text),
   canvasCtx: canvas.getContext'2d'),
   blockCtx: block.getContext'2d')
  })
 };
 _proto.initImg = function ) {
  var that = this;
  var isIE = window.navigator.userAgent.indexOf'Trident') > -1;
  var L = this.options.sliderL + this.options.sliderR * 2 + 3; // 滑块实际边长
  var drawImg = function ctx, operation) {
   var l = that.options.sliderL;
   var r = that.options.sliderR;
   var PI = that.options.PI;
   var x = that.x;
   var y = that.y;
   ctx.beginPath)
   ctx.moveTox, y)
   ctx.arcx + l / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI)
   ctx.lineTox + l, y)
   ctx.arcx + l + r - 2, y + l / 2, r, 1.21 * PI, 2.78 * PI)
   ctx.lineTox + l, y + l)
   ctx.lineTox, y + l)
   ctx.arcx + r - 2, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true)
   ctx.lineTox, y)
   ctx.lineWidth = 2
   ctx.fillStyle = 'rgba255, 255, 255, 0.7)'
   ctx.strokeStyle = 'rgba255, 255, 255, 0.7)'
   ctx.stroke)
   ctx[operation])
   ctx.globalCompositeOperation = isIE ? 'xor' : 'overlay'
  }
  var getRandomNumberByRange = function start, end) {
   return Math.roundMath.random) * end - start) + start);
  };
  var img = new Image);
  img.crossOrigin = "Anonymous";
  var loadCount = 0;
  img.onload = function ) {
   // 随机创建滑块的位置
   that.x = getRandomNumberByRangeL + 10, that.options.width - L + 10));
   that.y = getRandomNumberByRange10 + that.options.sliderR * 2, that.options.height - L + 10));
   drawImgthat.canvasCtx, 'fill');
   drawImgthat.blockCtx, 'clip');
   that.canvasCtx.drawImageimg, 0, 0, that.options.width - 2, that.options.height);
   that.blockCtx.drawImageimg, 0, 0, that.options.width - 2, that.options.height);
   var y = that.y - that.options.sliderR * 2 - 1;
   var ImageData = that.blockCtx.getImageDatathat.x - 3, y, L, L);
   that.block.width = L;
   that.blockCtx.putImageDataImageData, 0, y);
   that.text.textthat.text.attr'data-text'));
  };
  img.onerror = function ) {
   loadCount++;
   if window.location.protocol === 'file:') {
    loadCount = that.options.maxLoadCount;
    console.error"can't load pic resource file from File protocal. Please try http or https");
   }
   if loadCount >= that.options.maxLoadCount) {
    that.text.text'加载失败').addClass'text-danger');
    return;
   }
   img.src = that.options.localImages);
  };
  img.setSrc = function ) {
   var src = '';
   loadCount = 0;
   that.text.removeClass'text-danger');
   if $.isFunctionthat.options.setSrc)) src = that.options.setSrc);
   if !src || src === '') src = 'https://picsum.photos/' + that.options.width + '/' + that.options.height + '/?image=' + Math.roundMath.random) * 20);
   if isIE) { // IE浏览器无法通过img.crossOrigin跨域,使用ajax获取图片blob然后转为dataURL显示
    var xhr = new XMLHttpRequest)
    xhr.onloadend = function e) {
     var file = new FileReader); // FileReader仅支持IE10+
     file.readAsDataURLe.target.response);
     file.onloadend = function e) {
      img.src = e.target.result;
     }
    }
    xhr.open'GET', src);
    xhr.responseType = 'blob';
    xhr.send);
   } else img.src = src;
  };
  img.setSrc);
  this.text.attr'data-text', this.options.barText);
  this.text.textthis.options.loadingText);
  this.img = img
 };
 _proto.clean = function ) {
  this.canvasCtx.clearRect0, 0, this.options.width, this.options.height);
  this.blockCtx.clearRect0, 0, this.options.width, this.options.height);
  this.block.width = this.options.width;
 };
 _proto.bindEvents = function ) {
  var that = this;
  this.$element.on'selectstart', function ) {
   return false;
  });
  $this.refreshIcon).on'click', function ) {
   that.text.textthat.options.barText);
   that.reset);
   if $.isFunctionthat.options.onRefresh)) that.options.onRefresh.callthat.$element);
  });
  var originX, originY, trail = [],
   isMouseDown = false
  var handleDragStart = function e) {
   if that.text.hasClass'text-danger')) return;
   originX = e.clientX || e.touches[0].clientX;
   originY = e.clientY || e.touches[0].clientY;
   isMouseDown = true;
  };
  var handleDragMove = function e) {
   if !isMouseDown) return false;
   var eventX = e.clientX || e.touches[0].clientX;
   var eventY = e.clientY || e.touches[0].clientY;
   var moveX = eventX - originX;
   var moveY = eventY - originY;
   if moveX < 0 || moveX + 40 > that.options.width) return false;
   that.slider.style.left = moveX - 1) + 'px';
   var blockLeft = that.options.width - 40 - 20) / that.options.width - 40) * moveX;
   that.block.style.left = blockLeft + 'px';
   that.sliderContainer.addClass'sliderContainer_active');
   that.sliderMask.style.width = moveX + 4) + 'px';
   trail.pushmoveY);
  };
  var handleDragEnd = function e) {
   if !isMouseDown) return false
   isMouseDown = false
   var eventX = e.clientX || e.changedTouches[0].clientX
   if eventX == originX) return false
   that.sliderContainer.removeClass'sliderContainer_active');
   that.trail = trail
   var {
    spliced,
    verified
   } = that.verify)
   if spliced && verified) {
    that.sliderContainer.addClass'sliderContainer_success');
    if $.isFunctionthat.options.onSuccess)) that.options.onSuccess.callthat.$element);
   } else {
    that.sliderContainer.addClass'sliderContainer_fail');
    if $.isFunctionthat.options.onFail)) that.options.onFail.callthat.$element);
    setTimeout) => {
     that.text.textthat.options.failedText);
     that.reset);
    }, 1000);
   }
  };
  this.slider.addEventListener'mousedown', handleDragStart);
  this.slider.addEventListener'touchstart', handleDragStart);
  document.addEventListener'mousemove', handleDragMove);
  document.addEventListener'touchmove', handleDragMove);
  document.addEventListener'mouseup', handleDragEnd);
  document.addEventListener'touchend', handleDragEnd);
  document.addEventListener'mousedown', function ) { return false; });
  document.addEventListener'touchstart', function ) { return false; });
 };
 _proto.verify = function ) {
  var sum = function x, y) { return x + y; };
  var square = function x) { return x * x; };
  var arr = this.trail // 拖动时y轴的移动距离
  var average = arr.reducesum) / arr.length;
  var deviations = arr.mapfunction x) { return x - average; });
  var stddev = Math.sqrtdeviations.mapsquare).reducesum) / arr.length);
  var left = parseIntthis.block.style.left);
  return {
   spliced: Math.absleft - this.x) < this.options.offset,
   verified: stddev !== 0, // 简单验证下拖动轨迹,为零时表示Y轴上下没有波动,可能非人为操作
  }
 };
 _proto.reset = function ) {
  this.sliderContainer.removeClass'sliderContainer_fail sliderContainer_success');
  this.slider.style.left = 0
  this.block.style.left = 0
  this.sliderMask.style.width = 0
  this.clean)
  this.text.attr'data-text', this.text.text));
  this.text.textthis.options.loadingText);
  this.img.setSrc);
 };
})jQuery);

jquery是什么

jquery是一个简洁而快速的JavaScript库,它具有独特的链式语法和短小清晰的多功能接口、高效灵活的css选择器,并且可对CSS选择器进行扩展、拥有便捷的插件扩展机制和丰富的插件,是继Prototype之后又一个优秀的JavaScript代码库,能够用于简化事件处理、HTML文档遍历、Ajax交互和动画,以便快速开发网站。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注