转:前端滑动验证+拼图滑动验证效果

相信大家都玩过B站,B站在登陆的时候有个拼图滑动验证,今天就整合一下前端实现的滑动验证

拖动滑动验证(无背景图片)

  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5 <title>拖动滑块验证</title>
  6 </head>
  7 <body>
  8   <meta charset="utf8">
  9     <style>
 10         /* 滑动控件容器,灰色背景 */
 11         #dragContainer {
 12             position: relative;
 13             display: inline-block;
 14             background: #e8e8e8;
 15             width: 300px;
 16             height: 33px;
 17             border: 2px solid #e8e8e8;
 18         }
 19         /* 滑块左边部分,绿色背景 */
 20         #dragBg {
 21             position: absolute;
 22             background-color: #7ac23c;
 23             width: 0px;
 24             height: 100%;
 25         }
 26         /* 滑动验证容器文本 */
 27         #dragText {
 28             position: absolute;
 29             width: 100%;
 30             height: 100%;
 31             /* 文字水平居中 */
 32             text-align: center;
 33             /* 文字垂直居中,这里不能用百分比,因为百分比是相对原始line-height的,而非div高度 */
 34             line-height: 33px;
 35             /* 文本不允许选中 */
 36             user-select: none;
 37             -webkit-user-select: none;
 38         }
 39         /* 滑块 */
 40         #dragHandler {
 41             position: absolute;
 42             width: 40px;
 43             height: 100%;
 44             cursor: move;
 45         }
 46         /* 滑块初始背景 */
 47         .dragHandlerBg {
 48             background: #fff no-repeat center url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTEyNTVEMURGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTEyNTVEMUNGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MTc5NzNmZS02OTQxLTQyOTYtYTIwNi02NDI2YTNkOWU5YmUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+YiRG4AAAALFJREFUeNpi/P//PwMlgImBQkA9A+bOnfsIiBOxKcInh+yCaCDuByoswaIOpxwjciACFegBqZ1AvBSIS5OTk/8TkmNEjwWgQiUgtQuIjwAxUF3yX3xyGIEIFLwHpKyAWB+I1xGSwxULIGf9A7mQkBwTlhBXAFLHgPgqEAcTkmNCU6AL9d8WII4HOvk3ITkWJAXWUMlOoGQHmsE45ViQ2KuBuASoYC4Wf+OUYxz6mQkgwAAN9mIrUReCXgAAAABJRU5ErkJggg==");
 49         }
 50         /* 验证成功时的滑块背景 有√*/
 51         .dragHandlerOkBg {
 52             background: #fff no-repeat center url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDlBRDI3NjVGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDlBRDI3NjRGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDphNWEzMWNhMC1hYmViLTQxNWEtYTEwZS04Y2U5NzRlN2Q4YTEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+k+sHwwAAASZJREFUeNpi/P//PwMyKD8uZw+kUoDYEYgloMIvgHg/EM/ptHx0EFk9I8wAoEZ+IDUPiIMY8IN1QJwENOgj3ACo5gNAbMBAHLgAxA4gQ5igAnNJ0MwAVTsX7IKyY7L2UNuJAf+AmAmJ78AEDTBiwGYg5gbifCSxFCZoaBMCy4A4GOjnH0D6DpK4IxNSVIHAfSDOAeLraJrjgJp/AwPbHMhejiQnwYRmUzNQ4VQgDQqXK0ia/0I17wJiPmQNTNBEAgMlQIWiQA2vgWw7QppBekGxsAjIiEUSBNnsBDWEAY9mEFgMMgBk00E0iZtA7AHEctDQ58MRuA6wlLgGFMoMpIG1QFeGwAIxGZo8GUhIysmwQGSAZgwHaEZhICIzOaBkJkqyM0CAAQDGx279Jf50AAAAAABJRU5ErkJggg==");
 53         }
 54     </style>
 55     <script>
 56        //加载(事件会在页面加载完成后触发)
 57         window.onload = function() {
 58             //获取滑动控件容器,灰色背景
 59             var dragContainer = document.getElementById("dragContainer");
 60             //获取滑块左边部分,绿色背景
 61             var dragBg = document.getElementById("dragBg");
 62             //获取滑动验证容器文本
 63             var dragText = document.getElementById("dragText");
 64             //获取滑块
 65             var dragHandler = document.getElementById("dragHandler");
 66 
 67             //滑块的最大偏移量                 =     滑动验证容器文本长度                  -      滑块长度
 68             var maxHandlerOffset = dragContainer.clientWidth - dragHandler.clientWidth;
 69             //是否验证成功的标记
 70             var isVertifySucc = false;
 71             
 72             initDrag();
 73  
 74             function initDrag() {
 75                 //在滑动验证容器文本写入“拖动滑块验证”
 76                 dragText.textContent = "拖动滑块验证";
 77                 //给滑块添加鼠标按下监听
 78                 dragHandler.addEventListener("mousedown", onDragHandlerMouseDown);
 79             }
 80              
 81            //选中滑块
 82             function onDragHandlerMouseDown() {
 83                 //鼠标移动监听
 84                 document.addEventListener("mousemove", onDragHandlerMouseMove);
 85                 //鼠标松开监听
 86                 document.addEventListener("mouseup",  onDragHandlerMouseUp);
 87             }
 88              
 89            //滑块移动
 90             function onDragHandlerMouseMove() {
 91                 /*
 92                 html元素不存在width属性,只有clientWidth
 93                 offsetX是相对当前元素的,clientX和pageX是相对其父元素的
 94                 */
 95                //滑块移动量
 96                 var left = event.clientX - dragHandler.clientWidth / 2;
 97                 //
 98                 if(left < 0) {
 99                     left = 0;
100                  //如果滑块移动量   > 滑块的最大偏移量 ,则调用验证成功函数
101                 } else if(left > maxHandlerOffset) {
102                     left = maxHandlerOffset;
103                     verifySucc();
104                 }
105                 //滑块移动量
106                 dragHandler.style.left = left + "px";
107                 //绿色背景的长度
108                 dragBg.style.width = dragHandler.style.left;
109             }
110             
111            //松开滑块函数
112             function onDragHandlerMouseUp() {
113                 //移除鼠标移动监听
114                 document.removeEventListener("mousemove", onDragHandlerMouseMove);
115                 //移除鼠标松开监听
116                 document.removeEventListener("mouseup", onDragHandlerMouseUp);
117                 //初始化滑块移动量
118                 dragHandler.style.left = 0;
119                 //初始化绿色背景
120                 dragBg.style.width = 0;
121             }
122 
123             //验证成功
124             function verifySucc() {
125                 //成功标记,不可回弹
126                 isVertifySucc = false;
127                 //容器文本的文字改为白色“验证通过”字体
128                 dragText.textContent = "验证通过";
129                 dragText.style.color = "white";
130                 //验证通过的滑块背景
131                 dragHandler.setAttribute("class", "dragHandlerOkBg");
132                 //移除鼠标按下监听
133                 dragHandler.removeEventListener("mousedown", onDragHandlerMouseDown);
134                 //移除 鼠标移动监听
135                 document.removeEventListener("mousemove", onDragHandlerMouseMove);
136                 //移除鼠标松开监听
137                 document.removeEventListener("mouseup", onDragHandlerMouseUp);
138                 // 匹配成功以后写入你要跳转的页面
139                 window.location.href="成功页面.html";
140             };
141         }
142     </script>
143 </head>
144 <body>
145     <div id="dragContainer"><!-- 容器初始背景 -->
146         <div id="dragBg"></div><!-- 绿色背景 -->
147         <div id="dragText"></div><!-- 滑动容器文本 -->
148         <div id="dragHandler" class="dragHandlerBg"></div>
149     </div> <!--    滑块         滑块初始背景 -->
150 </body>
151 </html>

效果图:

图片滑动验证

 css

  1 .block {
  2   position: absolute;
  3   left: 0;
  4   top: 0;
  5 }
  6  
  7 .sliderContainer {
  8   position: relative;
  9   text-align: center;
 10   width: 310px;
 11   height: 40px;
 12   line-height: 40px;
 13   margin-top: 15px;
 14   background: #f7f9fa;
 15   color: #45494c;
 16   border: 1px solid #e4e7eb;
 17 }
 18  
 19 .sliderContainer_active .slider {
 20   height: 38px;
 21   top: -1px;
 22   border: 1px solid #1991FA;
 23 }
 24  
 25 .sliderContainer_active .sliderMask {
 26   height: 38px;
 27   border-width: 1px;
 28 }
 29  
 30 .sliderContainer_success .slider {
 31   height: 38px;
 32   top: -1px;
 33   border: 1px solid #52CCBA;
 34   background-color: #52CCBA !important;
 35 }
 36  
 37 .sliderContainer_success .sliderMask {
 38   height: 38px;
 39   border: 1px solid #52CCBA;
 40   background-color: #D2F4EF;
 41 }
 42  
 43 .sliderContainer_success .sliderIcon {
 44   background-position: 0 0 !important;
 45 }
 46  
 47 .sliderContainer_fail .slider {
 48   height: 38px;
 49   top: -1px;
 50   border: 1px solid #f57a7a;
 51   background-color: #f57a7a !important;
 52 }
 53  
 54 .sliderContainer_fail .sliderMask {
 55   height: 38px;
 56   border: 1px solid #f57a7a;
 57   background-color: #fce1e1;
 58 }
 59  
 60 .sliderContainer_fail .sliderIcon {
 61   top: 14px;
 62   background-position: 0 -82px !important;
 63 }
 64 .sliderContainer_active .sliderText, .sliderContainer_success .sliderText, .sliderContainer_fail .sliderText {
 65   display: none;
 66 }
 67  
 68 .sliderMask {
 69   position: absolute;
 70   left: 0;
 71   top: 0;
 72   height: 40px;
 73   border: 0 solid #1991FA;
 74   background: #D1E9FE;
 75 }
 76  
 77 .slider {
 78   position: absolute;
 79   top: 0;
 80   left: 0;
 81   width: 40px;
 82   height: 40px;
 83   background: #fff;
 84   box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);
 85   cursor: pointer;
 86   transition: background .2s linear;
 87 }
 88  
 89 .slider:hover {
 90   background: #1991FA;
 91 }
 92  
 93 .slider:hover .sliderIcon {
 94   background-position: 0 -13px;
 95 }
 96  
 97 .sliderIcon {
 98   position: absolute;
 99   top: 15px;
100   left: 13px;
101   width: 14px;
102   height: 12px;
103   background: url(http://cstaticdun.126.net//2.6.3/images/icon_light.f13cff3.png) 0 -26px;
104   background-size: 34px 471px;
105 }
106  
107 .refreshIcon {
108   position: absolute;
109   right: 0;
110   top: 0;
111   width: 34px;
112   height: 34px;
113   cursor: pointer;
114   background: url(http://cstaticdun.126.net//2.6.3/images/icon_light.f13cff3.png) 0 -437px;
115   background-size: 34px 471px;
116 }

js

  1 (function (window) {
  2   const l = 42, // 滑块边长
  3     r = 9, // 滑块半径
  4     w = 310, // canvas宽度
  5     h = 155, // canvas高度
  6     PI = Math.PI
  7   const L = l + r * 2 + 3 // 滑块实际边长
  8  
  9   function getRandomNumberByRange (start, end) {
 10     return Math.round(Math.random() * (end - start) + start)
 11   }
 12  
 13   function createCanvas (width, height) {
 14     const canvas = createElement('canvas')
 15     canvas.width = width
 16     canvas.height = height
 17     return canvas
 18   }
 19  
 20   function createImg (onload) {
 21     const img = createElement('img')
 22     img.crossOrigin = "Anonymous"
 23     img.onload = onload
 24     img.onerror = () => {
 25       img.src = getRandomImg()
 26     }
 27     img.src = getRandomImg()
 28     return img
 29   }
 30  
 31   function createElement (tagName, className) {
 32     const elment = document.createElement(tagName)
 33     elment.className = className
 34     return elment
 35   }
 36  
 37   function addClass (tag, className) {
 38     tag.classList.add(className)
 39   }
 40  
 41   function removeClass (tag, className) {
 42     tag.classList.remove(className)
 43   }
 44  
 45   function getRandomImg () {
 46     return 'https://picsum.photos/300/150/?image=' + getRandomNumberByRange(0, 1084)
 47   }
 48  
 49   function draw (ctx, x, y, operation) {
 50     ctx.beginPath()
 51     ctx.moveTo(x, y)
 52     ctx.arc(x + l / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI)
 53     ctx.lineTo(x + l, y)
 54     ctx.arc(x + l + r - 2, y + l / 2, r, 1.21 * PI, 2.78 * PI)
 55     ctx.lineTo(x + l, y + l)
 56     ctx.lineTo(x, y + l)
 57     ctx.arc(x + r - 2, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true)
 58     ctx.lineTo(x, y)
 59     ctx.lineWidth = 2
 60     ctx.fillStyle = 'rgba(255, 255, 255, 0.7)'
 61     ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)'
 62     ctx.stroke()
 63     ctx[operation]()
 64     ctx.globalCompositeOperation = 'overlay'
 65   }
 66  
 67   function sum (x, y) {
 68     return x + y
 69   }
 70  
 71   function square (x) {
 72     return x * x
 73   }
 74  
 75   class jigsaw {
 76     constructor ({ el, onSuccess, onFail, onRefresh }) {
 77       el.style.position = el.style.position || 'relative'
 78       this.el = el
 79       this.onSuccess = onSuccess
 80       this.onFail = onFail
 81       this.onRefresh = onRefresh
 82     }
 83  
 84     init () {
 85       this.initDOM()
 86       this.initImg()
 87       this.bindEvents()
 88     }
 89  
 90     initDOM () {
 91       const canvas = createCanvas(w, h) // 画布
 92       const block = canvas.cloneNode(true) // 滑块
 93       const sliderContainer = createElement('div', 'sliderContainer')
 94       const refreshIcon = createElement('div', 'refreshIcon')
 95       const sliderMask = createElement('div', 'sliderMask')
 96       const slider = createElement('div', 'slider')
 97       const sliderIcon = createElement('span', 'sliderIcon')
 98       const text = createElement('span', 'sliderText')
 99  
100       block.className = 'block'
101       text.innerHTML = '向右滑动填充拼图'
102  
103       const el = this.el
104       el.appendChild(canvas)
105       el.appendChild(refreshIcon)
106       el.appendChild(block)
107       slider.appendChild(sliderIcon)
108       sliderMask.appendChild(slider)
109       sliderContainer.appendChild(sliderMask)
110       sliderContainer.appendChild(text)
111       el.appendChild(sliderContainer)
112  
113       Object.assign(this, {
114         canvas,
115         block,
116         sliderContainer,
117         refreshIcon,
118         slider,
119         sliderMask,
120         sliderIcon,
121         text,
122         canvasCtx: canvas.getContext('2d'),
123         blockCtx: block.getContext('2d')
124       })
125     }
126  
127     initImg () {
128       const img = createImg(() => {
129         this.draw()
130         this.canvasCtx.drawImage(img, 0, 0, w, h)
131         this.blockCtx.drawImage(img, 0, 0, w, h)
132         const y = this.y - r * 2 - 1
133         const ImageData = this.blockCtx.getImageData(this.x - 3, y, L, L)
134         this.block.width = L
135         this.blockCtx.putImageData(ImageData, 0, y)
136       })
137       this.img = img
138     }
139  
140     draw () {
141       // 随机创建滑块的位置
142       this.x = getRandomNumberByRange(L + 10, w - (L + 10))
143       this.y = getRandomNumberByRange(10 + r * 2, h - (L + 10))
144       draw(this.canvasCtx, this.x, this.y, 'fill')
145       draw(this.blockCtx, this.x, this.y, 'clip')
146     }
147  
148     clean () {
149       this.canvasCtx.clearRect(0, 0, w, h)
150       this.blockCtx.clearRect(0, 0, w, h)
151       this.block.width = w
152     }
153  
154     bindEvents () {
155       this.el.onselectstart = () => false
156       this.refreshIcon.onclick = () => {
157         this.reset()
158         typeof this.onRefresh === 'function' && this.onRefresh()
159       }
160  
161       let originX, originY, trail = [], isMouseDown = false
162  
163       const handleDragStart = function (e) {
164         originX = e.clientX || e.touches[0].clientX
165         originY = e.clientY || e.touches[0].clientY
166         isMouseDown = true
167       }
168  
169       const handleDragMove = (e) => {
170         if (!isMouseDown) return false
171         const eventX = e.clientX || e.touches[0].clientX
172         const eventY = e.clientY || e.touches[0].clientY
173         const moveX = eventX - originX
174         const moveY = eventY - originY
175         if (moveX < 0 || moveX + 38 >= w) return false
176         this.slider.style.left = moveX + 'px'
177         const blockLeft = (w - 40 - 20) / (w - 40) * moveX
178         this.block.style.left = blockLeft + 'px'
179  
180         addClass(this.sliderContainer, 'sliderContainer_active')
181         this.sliderMask.style.width = moveX + 'px'
182         trail.push(moveY)
183       }
184  
185       const handleDragEnd = (e) => {
186         if (!isMouseDown) return false
187         isMouseDown = false
188         const eventX = e.clientX || e.changedTouches[0].clientX
189         if (eventX == originX) return false
190         removeClass(this.sliderContainer, 'sliderContainer_active')
191         this.trail = trail
192         const { spliced, verified } = this.verify()
193         if (spliced) {
194           if (verified) {
195             addClass(this.sliderContainer, 'sliderContainer_success')
196             typeof this.onSuccess === 'function' && this.onSuccess()
197           } else {
198             addClass(this.sliderContainer, 'sliderContainer_fail')
199             this.text.innerHTML = '再试一次'
200             this.reset()
201           }
202         } else {
203           addClass(this.sliderContainer, 'sliderContainer_fail')
204           typeof this.onFail === 'function' && this.onFail()
205           setTimeout(() => {
206             this.reset()
207           }, 1000)
208         }
209       }
210       this.slider.addEventListener('mousedown', handleDragStart)
211       this.slider.addEventListener('touchstart', handleDragStart)
212       document.addEventListener('mousemove', handleDragMove)
213       document.addEventListener('touchmove', handleDragMove)
214       document.addEventListener('mouseup', handleDragEnd)
215       document.addEventListener('touchend', handleDragEnd)
216     }
217  
218     verify () {
219       const arr = this.trail // 拖动时y轴的移动距离
220       const average = arr.reduce(sum) / arr.length
221       const deviations = arr.map(x => x - average)
222       const stddev = Math.sqrt(deviations.map(square).reduce(sum) / arr.length)
223       const left = parseInt(this.block.style.left)
224       return {
225         spliced: Math.abs(left - this.x) < 10,
226         verified: stddev !== 0, // 简单验证下拖动轨迹,为零时表示Y轴上下没有波动,可能非人为操作
227       }
228     }
229  
230     reset () {
231       this.sliderContainer.className = 'sliderContainer'
232       this.slider.style.left = 0
233       this.block.style.left = 0
234       this.sliderMask.style.width = 0
235       this.clean()
236       this.img.src = getRandomImg()
237     }
238  
239   }
240  
241   window.jigsaw = {
242     init: function (opts) {
243       return new jigsaw(opts).init()
244     }
245   }
246 }(window))

引用页面:

1 <link rel="stylesheet" href="../css/hdyz.css">
2 <script src="../js/myyz.js"></script>
3 <div id="captcha"></div>
4 <script type="text/javascript">
5   jigsaw.init({
6     el: document.getElementById('captcha'),
7   })
8 </script>

效果图:

 

 

文章转载自:https://www.cnblogs.com/huangting/p/11285131.html

posted @ 2021-03-01 16:59  傅丹辰cds  阅读(998)  评论(0编辑  收藏  举报