/** * 滑块验证 * @author good_idea * @date 2019年1月11日 上午10:48:41 */ layui.define(["jquery", "layer", "form"], function (exports) { "use strict"; var $ = layui.jquery, form = layui.form, layer = layui.layer, device = layui.device(), sliderVerify = { read: (function () { var css = ".slider-item{height:38px;line-height:38px;background-color:#d0d0d0;position:relative;border: 1px solid white;}.slider-bg{position:absolute;width:40px;height:100%;z-index:100}.slider-btn{width:40px;height:96%;position:absolute;border:1px solid #ccc;cursor:move;text-align:center;background-color:#fff;user-select:none;color:#666;z-index:120}.slider-btn-success{font-size:26px}.slider-text{position:absolute;text-align:center;width:100%;height:100%;user-select:none;font-size:14px;color:#fff;z-index:120}.slider-error{animation:glow 800ms ease-out infinite alternate;}@keyframes glow{0%{border-color:#e6e6e6}100%{border-color:#ff5722}}", style = document.createElement("style"); style.innerHTML = css; style.type = "text/css"; ($("head link:last")[0] && $("head link:last").after(style)) || $("head").append(style); })() }, dom = function (d) { return d[0]; }, thisSliderVerify = function () { var that = this; return { isOk: function () { return that.isOk.call(that); }, reset: function () { return that.reset.call(that); }, version: '1.7' }; }, MOD_NAME = "sliderVerify", MOD_BTN = "slider-btn", MOD_BG = "slider-bg", MOD_TEXT = "slider-text", MOD_NEXT = "layui-icon-next", MOD_OK = "layui-icon-ok-circle", MOD_BTN_SUCCESS = "slider-btn-success", MOD_DEFAULT_BG = "layui-bg-green", MOD_ERROR_BORDER = "slider-error", MOD_CONFIG_TEXT = "请拖动滑块验证", MOD_CONFIG_SUCCESS = "验证通过", Class = function (option) { var that = this; that.config = $.extend({}, that.config, option); that.render(); }; //默认配置 Class.prototype.config = { elem: "", onOk: null, isOk: false, isAutoVerify: true, bg: MOD_DEFAULT_BG, //默认滑块颜色 text: MOD_CONFIG_TEXT }; Class.prototype.render = function () { var that = this, option = that.config, elem = $(option.elem); if (!elem[0]) return; if (option.domid) option.domid.remove(); option.domid = that.createIdNum(); var sliderDom = $( [ '
', '
', '
' + option.text + "
", '
' ].join("") ); elem.hide().after(sliderDom); option.domid = $("#" + option.domid); that.events(); //自动验证 if (option.isAutoVerify) { form.verify({ sliderVerify: function (value, dom) { if (!value) { dom.classList.add(MOD_ERROR_BORDER); return option.text; } } }); } }; Class.prototype.isMobile = function () { return ( device.os == "ios" || device.os == "android" || device.android || device.ios ) || (device.weixin && typeof device.weixin === Boolean); }; Class.prototype.createIdNum = function () { return ( MOD_NAME + (+new Date()).toString() + Math.random() .toString() .substr(2, 7) ); }; //验证是否验证成功 Class.prototype.isOk = function () { return this.config.isOk; }; Class.prototype.error = function (msg) { return layer.msg(msg, { icon: 5 }); }; Class.prototype.distance = function () { var container = this.config.container; return container.box.offsetWidth - container.btn.offsetWidth; //滑动成功的宽度(距离) }; //重置组件 Class.prototype.reset = function () { this.config.isOk = false; return this.render(); }; //重置 Class.prototype.resize = function (distance) { var that = this, container = that.config.container; var distance = distance || that.distance(); container.btn.style.left = distance + "px"; container.bg.style.width = distance + "px"; }; //取消动画 Class.prototype.cancelTransition = function () { var container = this.config.container; this.config.domid[0].classList.remove(MOD_ERROR_BORDER); container.btn.style.transition = ""; container.bg.style.transition = ""; }; //按下 Class.prototype.down = function (e) { var that = this, option = that.config, container = option.container, e = e || window.event, //按下的坐标 downX = e.clientX || e.touches[0].clientX; //每次将过渡去掉 that.cancelTransition(); var move = function (e) { that.move(downX, e); }; that.events.move = move; //mobile移动 if (that.isMobile()) { document.addEventListener("touchmove", that.events.move); } else { //pc移动 document.onmousemove = move; } //处理部分浏览器滑动时左右翻页 if(navigator.userAgent.indexOf("UCBrowser") > -1){ e.preventDefault() } }; //移动 Class.prototype.move = function (down, e) { var that = this, option = that.config, container = option.container; var e = e || window.event; //鼠标移动后的水平位置 var moveX = e.clientX || e.touches[0].clientX; //鼠标水平位置的偏移量(鼠标移动时的位置 - 鼠标按下时的位置) var offsetX = moveX - down; //判断一下:鼠标水平移动的距离 与 滑动成功的距离 之间的关系 if (offsetX > container.distance) { offsetX = container.distance; //如果滑过了终点,就将它停留在终点位置 } else if (offsetX < 0) { offsetX = 0; //滑到了起点的左侧,将它重置为起点位置 } container.btn.style.left = offsetX + "px"; container.bg.style.width = offsetX + "px"; //鼠标的水平移动距离 = 滑动成功的宽度 if (offsetX == container.distance) { //1.滑动成功后的样式 container.text.innerHTML = MOD_CONFIG_SUCCESS; var com = window.getComputedStyle ? window.getComputedStyle(container.bg, null) : container.bg.currentStyle; container.btn.style.border = "1px solid " + com.backgroundColor; container.btn.style.color = com.backgroundColor; container.btn.classList.remove(MOD_NEXT); container.btn.classList.add(MOD_OK, MOD_BTN_SUCCESS); option.isOk = true; container.box.value = true; //成功后,清除掉鼠标按下事件和移动事件(因为移动时并不会涉及到鼠标松开事件) //干掉mobile事件 if (that.isMobile()) { container.btn.removeEventListener( "touchstart", that.events.down, false ); document.removeEventListener( "touchmove", that.events.move, false ); } else { container.btn.onmousedown = null; document.onmousemove = null; } //最后调用回调 option.onOk && typeof option.onOk == "function" && option.onOk(); return; } var seup = function (e) { that.stop(e); }; that.events.seup = seup; if (that.isMobile()) { document.addEventListener("touchend", seup); } else { document.onmouseup = seup; } }; //放开 Class.prototype.stop = function (e) { var that = this, option = that.config, container = option.container; //鼠标松开,如果滑到了终点,则验证通过 if (that.isOk()) { return; } else { container.btn.style.left = 0; container.bg.style.width = 0; container.btn.style.transition = "left 1s"; container.bg.style.transition = "width 1s"; } //鼠标松开了,不需要拖动就清除鼠标移动和松开事件。 document.onmousemove = null; document.onmouseup = null; if (that.isMobile()) { document.removeEventListener("touchmove", that.events.move, false); document.removeEventListener("touchend", that.events.seup, false); } }; //事件 Class.prototype.events = function () { var that = this, option = that.config; if (!option.domid) return that.error("创建滑块验证失败"); var btn = option.domid.find("." + MOD_BTN), bg = option.domid.find("." + MOD_BG), text = option.domid.find("." + MOD_TEXT), container = { box: dom(option.domid), btn: dom(btn), bg: dom(bg), text: dom(text) }; option.container = container; container.distance = that.distance(); var down = function (e) { that.down(e); }; that.events.down = down; if (that.isMobile()) { container.btn.addEventListener("touchstart", that.events.down); } else { container.btn.onmousedown = down; } var $dom = $(window); $dom.on("resize", option.domid, function () { if (that.config.isOk) { //重新计算页面被拉伸 that.resize(); }else{ that.render(); } }); }; sliderVerify.render = function (option) { var inst = new Class(option); return thisSliderVerify.call(inst); }; exports(MOD_NAME, sliderVerify); });