diff --git a/src/bundleconfig.json b/src/bundleconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..e11e1632ba55f3c7a00f489afe581dd405ac698c --- /dev/null +++ b/src/bundleconfig.json @@ -0,0 +1,19 @@ +[ + { + "outputFileName": "disk/slidercaptcha.min.css", + "inputFiles": [ + "disk/!(*.min).css" + ] + }, + { + "outputFileName": "disk/longbow.slidercaptcha.min.js", + "inputFiles": [ + "disk/longbow.slidercaptcha.js" + ], + "minify": { + "enabled": true, + "renameLocals": true + }, + "sourceMap": true + } +] \ No newline at end of file diff --git a/src/disk/longbow.slidercaptcha.js b/src/disk/longbow.slidercaptcha.js index 45297020329a57ae7bd86412fdc9c391784b71be..e3aa8aced6ee7895c220b22d89587fdf924b97f5 100644 --- a/src/disk/longbow.slidercaptcha.js +++ b/src/disk/longbow.slidercaptcha.js @@ -1,10 +1,38 @@ -(function ($) { +(function () { 'use strict'; + var extend = function () { + var length = arguments.length; + var target = arguments[0] || {}; + if (typeof target != "object" && typeof target != "function") { + target = {}; + } + if (length == 1) { + target = this; + i--; + } + for (var i = 1; i < length; i++) { + var source = arguments[i]; + for (var key in source) { + // 使用for in会遍历数组所有的可枚举属性,包括原型。 + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + return target; + } + + var isFunction = function isFunction(obj) { + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; + 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.$element = element; + this.options = extend({}, SliderCaptcha.DEFAULTS, options); + this.$element.style.position = 'relative'; + this.$element.style.width = this.options.width + 'px'; + this.$element.style.margin = '0 auto'; this.init(); }; @@ -27,17 +55,15 @@ }, verify: function (arr, url) { var ret = false; - $.ajax({ - url: url, - data: JSON.stringify(arr), - async: false, - cache: false, - type: 'POST', - contentType: 'application/json', - dataType: 'json', - success: function (result) { - ret = result; - } + fetch(url, { + method: 'post', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify(arr) + }).then(function (result) { + ret = result; }); return ret; }, @@ -45,19 +71,13 @@ }; function Plugin(option) { - return this.each(function () { - var $this = $(this); - var data = $this.data('lgb.SliderCaptcha'); - var options = typeof option === 'object' && option; - - if (data && !/reset/.test(option)) return; - if (!data) $this.data('lgb.SliderCaptcha', data = new SliderCaptcha(this, options)); - if (typeof option === 'string') data[option](); - }); + var $this = document.getElementById(option.id); + var options = typeof option === 'object' && option; + return new SliderCaptcha($this, options); } - $.fn.sliderCaptcha = Plugin; - $.fn.sliderCaptcha.Constructor = SliderCaptcha; + window.sliderCaptcha = Plugin; + window.sliderCaptcha.Constructor = SliderCaptcha; var _proto = SliderCaptcha.prototype; _proto.init = function () { @@ -94,34 +114,34 @@ text.innerHTML = this.options.barText; var el = this.$element; - el.append($(canvas)); - el.append($(refreshIcon)); - el.append($(block)); + el.appendChild(canvas); + el.appendChild(refreshIcon); + el.appendChild(block); slider.appendChild(sliderIcon); sliderMask.appendChild(slider); sliderContainer.appendChild(sliderbg); sliderContainer.appendChild(sliderMask); sliderContainer.appendChild(text); - el.append($(sliderContainer)); + el.appendChild(sliderContainer); var _canvas = { canvas: canvas, block: block, - sliderContainer: $(sliderContainer), + sliderContainer: sliderContainer, refreshIcon: refreshIcon, slider: slider, sliderMask: sliderMask, sliderIcon: sliderIcon, - text: $(text), + text: text, canvasCtx: canvas.getContext('2d'), blockCtx: block.getContext('2d') }; - if ($.isFunction(Object.assign)) { + if (isFunction(Object.assign)) { Object.assign(this, _canvas); } else { - $.extend(this, _canvas); + extend(this, _canvas); } }; @@ -171,7 +191,7 @@ var ImageData = that.blockCtx.getImageData(that.x - 3, y, L, L); that.block.width = L; that.blockCtx.putImageData(ImageData, 0, y + 1); - that.text.text(that.text.attr('data-text')); + that.text.textContent = that.text.getAttribute('data-text'); }; img.onerror = function () { loadCount++; @@ -180,7 +200,8 @@ 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'); + that.text.textContent = '加载失败'; + that.classList.add('text-danger'); return; } img.src = that.options.localImages(); @@ -188,8 +209,8 @@ img.setSrc = function () { var src = ''; loadCount = 0; - that.text.removeClass('text-danger'); - if ($.isFunction(that.options.setSrc)) src = that.options.setSrc(); + that.text.classList.remove('text-danger'); + if (isFunction(that.options.setSrc)) src = that.options.setSrc(); if (!src || src === '') src = 'https://picsum.photos/' + that.options.width + '/' + that.options.height + '/?image=' + Math.round(Math.random() * 20); if (isIE) { // IE浏览器无法通过img.crossOrigin跨域,使用ajax获取图片blob然后转为dataURL显示 var xhr = new XMLHttpRequest(); @@ -206,8 +227,8 @@ } else img.src = src; }; img.setSrc(); - this.text.attr('data-text', this.options.barText); - this.text.text(this.options.loadingText); + this.text.setAttribute('data-text', this.options.barText); + this.text.textContent = this.options.loadingText; this.img = img; }; @@ -219,21 +240,21 @@ _proto.bindEvents = function () { var that = this; - this.$element.on('selectstart', function () { + this.$element.addEventListener('selectstart', function () { return false; }); - $(this.refreshIcon).on('click', function () { + this.refreshIcon.addEventListener('click', function () { that.text.text(that.options.barText); that.reset(); - if ($.isFunction(that.options.onRefresh)) that.options.onRefresh.call(that.$element); + if (isFunction(that.options.onRefresh)) that.options.onRefresh.call(that.$element); }); var originX, originY, trail = [], isMouseDown = false; var handleDragStart = function (e) { - if (that.text.hasClass('text-danger')) return; + if (that.text.classList.contains('text-danger')) return; originX = e.clientX || e.touches[0].clientX; originY = e.clientY || e.touches[0].clientY; isMouseDown = true; @@ -250,7 +271,7 @@ var blockLeft = (that.options.width - 40 - 20) / (that.options.width - 40) * moveX; that.block.style.left = blockLeft + 'px'; - that.sliderContainer.addClass('sliderContainer_active'); + that.sliderContainer.classList.add('sliderContainer_active'); that.sliderMask.style.width = (moveX + 4) + 'px'; trail.push(Math.round(moveY)); }; @@ -260,15 +281,15 @@ isMouseDown = false; var eventX = e.clientX || e.changedTouches[0].clientX; if (eventX === originX) return false; - that.sliderContainer.removeClass('sliderContainer_active'); + that.sliderContainer.classList.remove('sliderContainer_active'); that.trail = trail; var data = that.verify(); if (data.spliced && data.verified) { - that.sliderContainer.addClass('sliderContainer_success'); - if ($.isFunction(that.options.onSuccess)) that.options.onSuccess.call(that.$element); + that.sliderContainer.classList.add('sliderContainer_success'); + if (isFunction(that.options.onSuccess)) that.options.onSuccess.call(that.$element); } else { - that.sliderContainer.addClass('sliderContainer_fail'); - if ($.isFunction(that.options.onFail)) that.options.onFail.call(that.$element); + that.sliderContainer.classList.add('sliderContainer_fail'); + if (isFunction(that.options.onFail)) that.options.onFail.call(that.$element); setTimeout(function () { that.text.text(that.options.failedText); that.reset(); @@ -310,13 +331,14 @@ }; _proto.reset = function () { - this.sliderContainer.removeClass('sliderContainer_fail sliderContainer_success'); + this.sliderContainer.classList.remove('sliderContainer_fail'); + this.sliderContainer.classList.remove('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.text(this.options.loadingText); + this.text.setAttribute('data-text', this.text.textContent); + this.text.textContent = this.options.loadingText; this.img.setSrc(); }; -})(jQuery); \ No newline at end of file +})(); \ No newline at end of file diff --git a/src/disk/longbow.slidercaptcha.min.js b/src/disk/longbow.slidercaptcha.min.js new file mode 100644 index 0000000000000000000000000000000000000000..27fa8145df57e2d37aa8e14cb5c8cd23e89dc131 --- /dev/null +++ b/src/disk/longbow.slidercaptcha.min.js @@ -0,0 +1,2 @@ +(function(){"use strict";function u(n){var i=document.getElementById(n.id),r=typeof n=="object"&&n;return new t(i,r)}var r=function(){var u=arguments.length,n=arguments[0]||{},t,i,r;for(typeof n!="object"&&typeof n!="function"&&(n={}),u==1&&(n=this,t--),t=1;t-1,r=this.options.sliderL+this.options.sliderR*2+3,e=function(t,i){var r=n.options.sliderL,o=n.options.sliderR,s=n.options.PI,u=n.x,e=n.y;t.beginPath();t.moveTo(u,e);t.arc(u+r/2,e-o+2,o,.72*s,2.26*s);t.lineTo(u+r,e);t.arc(u+r+o-2,e+r/2,o,1.21*s,2.78*s);t.lineTo(u+r,e+r);t.lineTo(u,e+r);t.arc(u+o-2,e+r/2,o+.4,2.76*s,1.24*s,!0);t.lineTo(u,e);t.lineWidth=2;t.fillStyle="rgba(255, 255, 255, 0.7)";t.strokeStyle="rgba(255, 255, 255, 0.7)";t.stroke();t[i]();t.globalCompositeOperation=f?"xor":"destination-over"},o=function(n,t){return Math.round(Math.random()*(t-n)+n)},t=new Image,u;t.crossOrigin="Anonymous";u=0;t.onload=function(){n.x=o(r+10,n.options.width-(r+10));n.y=o(10+n.options.sliderR*2,n.options.height-(r+10));e(n.canvasCtx,"fill");e(n.blockCtx,"clip");n.canvasCtx.drawImage(t,0,0,n.options.width-2,n.options.height);n.blockCtx.drawImage(t,0,0,n.options.width-2,n.options.height);var i=n.y-n.options.sliderR*2-1,u=n.blockCtx.getImageData(n.x-3,i,r,r);n.block.width=r;n.blockCtx.putImageData(u,0,i+1);n.text.textContent=n.text.getAttribute("data-text")};t.onerror=function(){if(u++,window.location.protocol==="file:"&&(u=n.options.maxLoadCount,console.error("can't load pic resource file from File protocal. Please try http or https")),u>=n.options.maxLoadCount){n.text.textContent="加载失败";n.classList.add("text-danger");return}t.src=n.options.localImages()};t.setSrc=function(){var r="",e;u=0;n.text.classList.remove("text-danger");i(n.options.setSrc)&&(r=n.options.setSrc());r&&r!==""||(r="https://picsum.photos/"+n.options.width+"/"+n.options.height+"/?image="+Math.round(Math.random()*20));f?(e=new XMLHttpRequest,e.onloadend=function(n){var i=new FileReader;i.readAsDataURL(n.target.response);i.onloadend=function(n){t.src=n.target.result}},e.open("GET",r),e.responseType="blob",e.send()):t.src=r};t.setSrc();this.text.setAttribute("data-text",this.options.barText);this.text.textContent=this.options.loadingText;this.img=t};n.clean=function(){this.canvasCtx.clearRect(0,0,this.options.width,this.options.height);this.blockCtx.clearRect(0,0,this.options.width,this.options.height);this.block.width=this.options.width};n.bindEvents=function(){var n=this;this.$element.addEventListener("selectstart",function(){return!1});this.refreshIcon.addEventListener("click",function(){n.text.text(n.options.barText);n.reset();i(n.options.onRefresh)&&n.options.onRefresh.call(n.$element)});var r,u,f=[],t=!1,e=function(i){n.text.classList.contains("text-danger")||(r=i.clientX||i.touches[0].clientX,u=i.clientY||i.touches[0].clientY,t=!0)},o=function(i){var o;if(!t)return!1;var s=i.clientX||i.touches[0].clientX,h=i.clientY||i.touches[0].clientY,e=s-r,c=h-u;if(e<0||e+40>n.options.width)return!1;n.slider.style.left=e-1+"px";o=(n.options.width-60)/(n.options.width-40)*e;n.block.style.left=o+"px";n.sliderContainer.classList.add("sliderContainer_active");n.sliderMask.style.width=e+4+"px";f.push(Math.round(c))},s=function(u){var o,e;if(!t||(t=!1,o=u.clientX||u.changedTouches[0].clientX,o===r))return!1;n.sliderContainer.classList.remove("sliderContainer_active");n.trail=f;e=n.verify();e.spliced&&e.verified?(n.sliderContainer.classList.add("sliderContainer_success"),i(n.options.onSuccess)&&n.options.onSuccess.call(n.$element)):(n.sliderContainer.classList.add("sliderContainer_fail"),i(n.options.onFail)&&n.options.onFail.call(n.$element),setTimeout(function(){n.text.text(n.options.failedText);n.reset()},1e3))};this.slider.addEventListener("mousedown",e);this.slider.addEventListener("touchstart",e);document.addEventListener("mousemove",o);document.addEventListener("touchmove",o);document.addEventListener("mouseup",s);document.addEventListener("touchend",s);document.addEventListener("mousedown",function(){return!1});document.addEventListener("touchstart",function(){return!1});document.addEventListener("swipe",function(){return!1})};n.verify=function(){var n=this.trail,r=parseInt(this.block.style.left),t=!1;if(this.options.remoteUrl!==null)t=this.options.verify(n,this.options.remoteUrl);else{var i=function(n,t){return n+t},u=function(n){return n*n},f=n.reduce(i)/n.length,e=n.map(function(n){return n-f}),o=Math.sqrt(e.map(u).reduce(i)/n.length);t=o!==0}return{spliced:Math.abs(r-this.x) Slider Captcha Demo - - +