js 拖动滑块验证
备注:拖动滑块时尽量平移,chrome浏览器上没有卡顿情况,但是搜狗极速模式和360极速模式都遇到了卡顿,拖不动情况,应是浏览器内部对事件响应速度导致吧。
JS代码:
;(function ($,window,document,undefined) {
function SliderUnlock(elm, options, success){
var me = this;
var $elm = me.checkElm(elm) ? $(elm) : $;
success = me.checkFn(success) ? success : function(){}; var opts = {
successLabelTip: "验证成功!",
defaultLabelTip: "拖动滑块验证!",
duration: 200,
swipestart: false,
min: 0,
max: $elm.width(),
index: 0,
IsOk: false,
lableIndex: 0
}; opts = $.extend(opts, options||{}); //$elm
me.elm = $elm;
//opts
me.opts = opts;
//是否鼠标移入状态
me.isIn = false;
//鼠标移出次数,防抖
me.outNum = 0;
//是否开始滑动
me.swipestart = opts.swipestart;
//最小值
me.min = opts.min;
//最大值
me.max = opts.max;
//当前滑动条所处的位置
me.index = opts.index;
//是否滑动成功
me.isOk = opts.isOk;
//滑块宽度
me.labelWidth = me.elm.find('#label').width();
//滑块背景
me.sliderBg = me.elm.find('#slider_bg');
//鼠标在滑动按钮的位置
me.lableIndex = opts.lableIndex;
//success
me.success = success;
} SliderUnlock.prototype.init = function () {
var me = this;
me.elm.find("#label").on("mousedown", function (event) {
var e = event || window.event;
me.lableIndex = e.clientX - this.offsetLeft;
me.handerIn();
}).on("mousemove", function (event) {
me.handerMove(event);
}).on("mouseup", function (event) {
me.handerOut();
}).on("mouseout", function (event) {
me.handerOut();
}).on("touchstart", function (event) {
var e = event || window.event;
me.lableIndex = e.originalEvent.touches[0].pageX - this.offsetLeft;
me.handerIn();
}).on("touchmove", function (event) {
me.handerMove(event, "mobile");
}).on("touchend", function (event) {
me.handerOut();
});
me.updateView();
}; /**
* 鼠标/手指接触滑动按钮
*/
SliderUnlock.prototype.handerIn = function () {
var me = this;
if (me.isIn)
return;
me.swipestart = true;
me.outNum = 0;
me.min = 0;
me.max = me.elm.width();
me.isIn = true;
}; /**
* 鼠标/手指移出
*/
SliderUnlock.prototype.handerOut = function () { var me = this;
if (!me.isIn)
return;
me.outNum = me.outNum + 1;
if (me.outNum == 2)
{
me.outNum = 0;
me.isIn = false;
//停止
me.swipestart = false;
//me.move();
if (me.index < me.max) {
me.reset();
}
}
}; /**
* 鼠标/手指移动
* @param event
* @param type
*/
SliderUnlock.prototype.handerMove = function (event, type) {
var me = this;
if (me.swipestart) {
event.preventDefault();
event = event || window.event;
if (type == "mobile") {
me.index = event.originalEvent.touches[0].pageX - me.lableIndex;
} else {
me.index = event.clientX - me.lableIndex;
}
me.move();
}
}; /**
* 鼠标/手指移动过程
*/
SliderUnlock.prototype.move = function () {
var me = this;
if ((me.index + me.labelWidth) >= me.max) {
me.index = me.max - me.labelWidth - 2;
//停止
me.swipestart = false;
//解锁
me.isOk = true;
}
if (me.index < 0) {
me.index = me.min;
//未解锁
me.isOk = false;
}
if (me.index + me.labelWidth + 2 == me.max && me.max > 0 && me.isOk) {
console.log("me.index + me.labelWidth + 2 == me.max && me.max > 0 && me.isOk");
//解锁默认操作
$('#label').unbind().next('#labelTip').
text(me.opts.successLabelTip).css({ 'color': '#fff' });
me.success();
}
me.updateView();
}; /**
* 更新视图
*/
SliderUnlock.prototype.updateView = function () {
var me = this;
me.sliderBg.css('width', me.index);
me.elm.find("#label").css("left", me.index + "px")
}; /**
* 是否验证通过
*/
SliderUnlock.prototype.isValidateOk = function () {
var me = this;
return me.isOk;
}; /**
* 重置slide的起点
*/
SliderUnlock.prototype.reset = function () {
var me = this;
me.isOk = false;
me.index = 0;
me.sliderBg.animate({ 'width': 0 }, me.opts.duration);
me.elm.find("#label").on("mousedown", function (event) {
var e = event || window.event;
me.lableIndex = e.clientX - this.offsetLeft;
me.handerIn();
}).on("mousemove", function (event) {
me.handerMove(event);
}).on("mouseup", function (event) {
me.handerOut();
}).on("mouseout", function (event) {
me.handerOut();
}).on("touchstart", function (event) {
var e = event || window.event;
me.lableIndex = e.originalEvent.touches[0].pageX - this.offsetLeft;
me.handerIn();
}).on("touchmove", function (event) {
me.handerMove(event, "mobile");
}).on("touchend", function (event) {
me.handerOut();
}).animate({ left: me.index }, me.opts.duration)
.next("#labelTip").text(me.opts.defaultLabelTip).css({ 'color': '#787878' })
.animate({ opacity: 1 }, me.opts.duration);
me.updateView();
}; /**
* 检测元素是否存在
* @param elm
* @returns {boolean}
*/
SliderUnlock.prototype.checkElm = function (elm) {
if($(elm).length > 0){
return true;
}else{
throw "this element does not exist.";
}
}; /**
* 检测传入参数是否是function
* @param fn
* @returns {boolean}
*/
SliderUnlock.prototype.checkFn = function (fn) {
if(typeof fn === "function"){
return true;
} else {
return false;
//throw "the param is not a function.";
}
}; window['SliderUnlock'] = SliderUnlock;
})(jQuery, window, document);
Css样式:
#slider {
margin: 10px auto;
width: 200px;
height: 30px;
position: relative;
border-radius:5px;
background-color: #dae2d0;
overflow: hidden;
text-align: center;
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
} #slider_bg {
position: absolute;
left:;
top:;
height: 100%;
background-color: #49ba43;
z-index:;
} #label {
width: 46px;
position: absolute;
left:;
top:;
height: 29px;
line-height: 29px;
border-radius:5px;
border: 1px solid #cccccc;
background: #fff;
z-index:;
cursor: move;
color: #ff9e77;
font-size: 18px;
font-weight:;
} #labelTip {
position: absolute;
left:;
width: 100%;
height: 100%;
font-size: 13px;
font-family: 'Microsoft Yahei', serif;
color: #787878;
line-height: 30px;
text-align: center;
z-index:;
}
前台调用:
<!--HTML-->
<div id="slider">
<div id="slider_bg"></div>
<span id="label">>></span>
<span id="labelTip">
拖动滑块验证
</span>
</div> //JS初始化
var slider;
$(function () {
slider = new SliderUnlock("#slider");
slider.init();
}); //重置
slider.reset();
说实话,如上代码,还是会出现卡顿,近期尝试了如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<meta http-equiv="X-UA-Compatible" content="IE-Edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<meta content="email=no" name="format-detection">
<title>拖动滑块验证</title>
<meta name="description" content="">
<meta name="keywords" content="">
<link rel="stylesheet" type="text/css" href="">
<style>
*{ margin:0; padding:0; }
body{ font:12px/1.125 Microsoft YaHei; background:#fff; }
ul, li{ list-style:none; }
a{ text-decoration:none; }
.ani{transition:all .3s;}
.wrap{ width:300px; height:350px; text-align:center; margin:150px auto;}
.inner{ padding:15px; }
.clearfix{ overflow:hidden; _zoom:1; }
.none{ display:none; }
#slider{position:relative;background-color:#e8e8e8;width:300px;height:34px;line-height:34px;text-align:center;}
#slider .handler{position:absolute;top:0px;left:0px;width:40px;height:32px;border:1px solid #ccc;cursor:move;}
.handler_bg{background:#fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTEyNTVEMURGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTEyNTVEMUNGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MTc5NzNmZS02OTQxLTQyOTYtYTIwNi02NDI2YTNkOWU5YmUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+YiRG4AAAALFJREFUeNpi/P//PwMlgImBQkA9A+bOnfsIiBOxKcInh+yCaCDuByoswaIOpxwjciACFegBqZ1AvBSIS5OTk/8TkmNEjwWgQiUgtQuIjwAxUF3yX3xyGIEIFLwHpKyAWB+I1xGSwxULIGf9A7mQkBwTlhBXAFLHgPgqEAcTkmNCU6AL9d8WII4HOvk3ITkWJAXWUMlOoGQHmsE45ViQ2KuBuASoYC4Wf+OUYxz6mQkgwAAN9mIrUReCXgAAAABJRU5ErkJggg==") no-repeat center;}
.handler_ok_bg{background:#fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDlBRDI3NjVGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDlBRDI3NjRGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDphNWEzMWNhMC1hYmViLTQxNWEtYTEwZS04Y2U5NzRlN2Q4YTEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+k+sHwwAAASZJREFUeNpi/P//PwMyKD8uZw+kUoDYEYgloMIvgHg/EM/ptHx0EFk9I8wAoEZ+IDUPiIMY8IN1QJwENOgj3ACo5gNAbMBAHLgAxA4gQ5igAnNJ0MwAVTsX7IKyY7L2UNuJAf+AmAmJ78AEDTBiwGYg5gbifCSxFCZoaBMCy4A4GOjnH0D6DpK4IxNSVIHAfSDOAeLraJrjgJp/AwPbHMhejiQnwYRmUzNQ4VQgDQqXK0ia/0I17wJiPmQNTNBEAgMlQIWiQA2vgWw7QppBekGxsAjIiEUSBNnsBDWEAY9mEFgMMgBk00E0iZtA7AHEctDQ58MRuA6wlLgGFMoMpIG1QFeGwAIxGZo8GUhIysmwQGSAZgwHaEZhICIzOaBkJkqyM0CAAQDGx279Jf50AAAAAABJRU5ErkJggg==") no-repeat center;}
#slider .drag_bg{background-color:#7ac23c;height:34px;width:0px;}
#slider .drag_text{position:absolute;top:0px;width:300px;-moz-user-select:none;-webkit-user-select:none;user-select:none;-o-user-select:none;-ms-user-select:none;}
.unselect{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;}
.slide_ok{color:#fff;}
</style>
</head>
<body> <div class="wrap">
<div id="slider">
<div class="drag_bg"></div>
<div class="drag_text" onselectstart="return false;" unselectable="on">拖动滑块验证</div>
<div class="handler handler_bg"></div>
</div>
</div> <script>
(function(window,document,undefined){
var dog = {//声明一个命名空间,或者称为对象
$:function(id){
return document.querySelector(id);
},
on:function(el,type,handler){
el.addEventListener(type,handler,false);
},
off:function(el,type,handler){
el.removeEventListener(type,handler,false);
}
};
//封装一个滑块类
function Slider(){
var args = arguments[0];
for(var i in args){
this[i] = args[i]; //一种快捷的初始化配置
}
//直接进行函数初始化,表示生成实例对象就会执行初始化
this.init();
}
Slider.prototype = {
constructor:Slider,
init:function(){
this.getDom();
this.dragBar(this.handler);
},
getDom:function(){
this.slider = dog.$('#'+this.id);
this.handler = dog.$('.handler');
this.bg = dog.$('.drag_bg');
},
dragBar:function(handler){
var that = this,
startX = 0,
lastX = 0,
doc = document,
width = this.slider.offsetWidth,
max = width - handler.offsetWidth,
drag = {
down:function(e){
var e = e||window.event;
that.slider.classList.add('unselect');
startX = e.clientX - handler.offsetLeft;
console.log('startX: '+startX+' px');
dog.on(doc,'mousemove',drag.move);
dog.on(doc,'mouseup',drag.up);
return false;
},
move:function(e){
var e = e||window.event;
lastX = e.clientX - startX;
lastX = Math.max(0,Math.min(max,lastX)); //这一步表示距离大于0小于max,巧妙写法
console.log('lastX: '+lastX+' px');
if(lastX>=max){
handler.classList.add('handler_ok_bg');
that.slider.classList.add('slide_ok');
dog.off(handler,'mousedown',drag.down);
drag.up();
}
that.bg.style.width = lastX + 'px';
handler.style.left = lastX + 'px'; },
up:function(e){
var e = e||window.event;
that.slider.classList.remove('unselect');
if(lastX < width){
that.bg.classList.add('ani');
handler.classList.add('ani');
that.bg.style.width = 0;
handler.style.left = 0;
setTimeout(function(){
that.bg.classList.remove('ani');
handler.classList.remove('ani');
},300); }
dog.off(doc,'mousemove',drag.move);
dog.off(doc,'mouseup',drag.up);
}
}; dog.on(handler,'mousedown',drag.down);
}
}; window.S = window.Slider = Slider; })(window,document); var defaults = {
id:'slider'
};
new S(defaults);
</script>
</body>
</html>
附:拖动轮播图片:http://www.jssor.com/demos/image-slider.slider
js 拖动滑块验证的更多相关文章
- JS拖动滑块验证
使用这种验证方法的目的:证明当前的用户不是机器人~防止恶意操作. 实现思路: 1.获取silde滑块(获取元素) 2.为元素注册事件———鼠标点击事件(onmousedown)鼠标点击之后获得当前鼠标 ...
- 原生js实现拖动滑块验证
拖动滑块验证是现在的网站随处可见的,各式各样的拖动法都有. 下面实现的是某宝的拖动滑块验证: <!DOCTYPE html> <html lang="en"> ...
- 原生JS实现拖动滑块验证登录效果
♀分享一组利用原生JS实现拖动滑块验证效果 ♀在这个组代码中涉及三个方面的知识: ⑴事件处理 ⑵添加验证标记 ⑶选择器的封装 代码如下: <!DOCTYPE html> <htm ...
- jQuery手机触屏拖动滑块验证跳转插件
HTML: <!DOCTYPE html> <html lang="en"> <head> <title>jQuery手机触屏拖动滑 ...
- 手把手教你做一个原生js拖动滑块【兼容PC和移动端】
废话少说: 在PC端可以用mousedown来触发一个滑块滑动的效果,但在手机上,貌似无法识别这个事件,但手机上有touchstart事件,可以通过一系列"touch"事件来替代P ...
- js登录滑动验证,不滑动无法登陆
js的判断这里是根据滑块的位置进行判断,应该是用一个flag判断 <%@ page language="java" contentType="text/html; ...
- js移动端滑块验证解锁组件
本文修改自PC端的js滑块验证组件,PC端使用的是onmousedown,onmouseup,nomousemove.原文找不到了,也是博客园文章,在此感谢广大网友的生产力吧. 说下对插件和组件的理解 ...
- js+css3+HTML5拖动滑块(type="range")改变值
最近在做一个H5的改版项目,产品和设计给出的效果中有一个拖动滑块可以改变输入值的效果,类似如下图这样: 拿到这样的设计稿后,我有点懵了,自己写一个js?去网上找一个这样的效果?自己写一个可以,只是实现 ...
- [Android实例] 拖动滑块进行图片拼合验证方式的实现
该篇文章从eoeAndroid搬迁过来的,原文地址:[Android实例] 拖动滑块进行图片拼合验证方式的实现 现在网站上有各种各样的验证码验证方式,比如计算大小,输入图片内容等,今天在一家网站上看到 ...
随机推荐
- 【转】Backbone.js学习笔记(一)
文章转自: http://segmentfault.com/a/1190000002386651 基本概念 前言 昨天开始学Backbone.js,写篇笔记记录一下吧,一直对MVC模式挺好奇的,也对j ...
- Block的声明与定义语法
Block的声明 Block的声明与函数指针的声明类似 返回值类型(^变量名)(参数列表) Block的定义 ^返回值类型(参数列表) { 表达式 } 其中: 1 如果返回值类型是void,可以省略 ...
- C语言 指针数组 多维数组
. 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21402047 . 1. 地址算数运算示例 指针算数运算 ...
- 【week2】四人小组项目(WBS、NABCD)
项目选题:东北师范大学论坛 小组名称:nice! 项目组长:李权 组员:于淼 刘芳芳 杨柳 本周任务:要求给出需求概述.功能列表.痛点或亮点.NABCD及WBS模型在此项目中的应用. 作为东北师范大学 ...
- PAT 1052 卖个萌
https://pintia.cn/problem-sets/994805260223102976/problems/994805273883951104 萌萌哒表情符号通常由“手”.“眼”.“口”三 ...
- win7 php连接远程oracle
<?php /* 先下载oracle客户端 下载地址 http://www.oracle.com/technetwork/topics/winx64soft-089540.html 下载如下三个 ...
- 相机上的P,S,A,M分别是什么单词的缩写?
程序曝光 Programmed Auto快门优先 Shutter Priority光圈优先 aperture-priority 全手动模式 Manual Mode
- 常见设备在linux中的文件名
设备 linux中的文件名 IDE硬盘 /dev/hd[a-d] SATA/USB/SCSI/SAS /dev/sd[a-p] 软盘 /dev/fd[0-1] 打印机 25针:/dev/lp[0-2] ...
- redis——持久化方式RDB与AOF分析
https://blog.csdn.net/u014229282/article/details/81121214 redis两种持久化的方式 RDB持久化可以在指定的时间间隔内生成数据集的时间点快照 ...
- Agile.Net 组件式开发平台 - 服务开发示例
在上一篇文章中已经讲解了组件的开发,这篇文章讲解平台服务开发. Agile.Net开发管理平台项目,已经托管在开源中国码云平台(http://git.oschina.net) 登陆码云平台进入项目主页 ...