小编给大家分享一下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交互和动画,以便快速开发网站。