123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- /**
- * 滑块验证
- * @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 = $(
- [
- '<div id="' +
- option.domid +
- '"' +
- (option.isAutoVerify ? 'lay-verify="sliderVerify"' : "") +
- 'class="slider-item">',
- '<div class="' + MOD_BG + " " + option.bg + '"></div>',
- '<div class="' + MOD_TEXT + '">' + option.text + "</div>",
- '<div class="' + MOD_BTN + ' layui-icon layui-icon-next"></div>'
- ].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);
- });
|