pp:今天在项目中遇到写拖动图片进行验证的需求,网上查找的插件库都需要有偿下载,所以就自己动手写了一个,放上来供有需要的人做参考,有疑问也欢迎留言,乐于做一个奉献的前端小傻狗~
1、先上预览图
1.1 最开始的样子
1.2拖动滑块 图片显示
1.3把滑块拖动到相应位置 图片隐藏
2、代码结构图 ps:此插件用到字体文件 不知道怎么插入文件 所以把名字放上来自己去下载 也可发邮箱转发给你
3、html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="./css/index.css">
<style>
#resetpwdVerify{
position: relative;
top: 300px;
left: 50%;
}
</style>
</head>
<body>
<div id="resetpwdVerify"></div>
<script src="./js/jquery.min.js"></script>
<script>
function initVerify() {
$('#resetpwdVerify').html('');
var that = this;
$('#resetpwdVerify').slideVerify({
type: 2, //类型
vOffset: 5, //误差量,根据需求自行调整
vSpace: 5, //间隔
imgName: ['1.jpg', '2.jpg', '3.jpg', '4.jpg'],
imgSize: {
width: '360px',
height: '200px',
},
blockSize: {
width: '40px',
height: '40px',
},
barSize: {
width: '360px',
height: '40px',
},
ready: function () {
},
success: function () {
},
error: function () {
}
});
}
$(function () {
initVerify()
});
; (function ($, window, document, undefined) {
//定义Slide的构造函数
var Slide = function (ele, opt) {
this.$element = ele,
this.defaults = {
num: 1,
type: 1,
vOffset: 5,
vSpace: 5,
imgName: ['1.jpg', '2.jpg', '3.jpg', '4.jpg'],
imgSize: {
width: '360px',
height: '200px',
},
blockSize: {
width: '50px',
height: '50px',
},
barSize: {
width: '360px',
height: '40px',
},
ready: function () { },
success: function () { },
error: function () { }
},
this.options = $.extend({}, this.defaults, opt)
};
//定义Slide的方法
Slide.prototype = {
init: function () {
var _this = this;
//加载页面
this.loadDom();
this.options.ready();
this.$element[0].onselectstart = document.body.ondrag = function () {
return false;
};
//按下
this.htmlDoms.move_block.on('touchstart', function (e) {
_this.start(e);
});
this.htmlDoms.move_block.on('mousedown', function (e) {
_this.start(e);
});
//拖动
window.addEventListener("touchmove", function (e) {
_this.move(e);
});
window.addEventListener("mousemove", function (e) {
_this.move(e);
});
//鼠标松开
window.addEventListener("touchend", function () {
_this.end();
});
window.addEventListener("mouseup", function () {
_this.end();
});
//刷新
_this.$element.find('.verify-refresh').on('click', function () {
_this.refresh();
});
},
//初始化加载
loadDom: function () {
this.img_rand = Math.floor(Math.random() * this.options.imgName.length); //随机的背景图片
var panelHtml = '';
var tmpHtml = '';
if (this.options.type != 1) {
panelHtml += '<div class="verify-img-panel"><div class="verify-refresh"><i class="iconfont icon-refresh"></i></div><div class="verify-gap"></div></div>';
tmpHtml = '<div class="verify-sub-block"></div>';
}
panelHtml += '<div class="verify-bar-area"><span class="verify-msg">向右滑动完成验证</span><div class="verify-left-bar"><span class="verify-msg"></span><div class="verify-move-block"><i class="verify-icon iconfont icon-right"></i>' + tmpHtml + '</div></div></div>';
this.$element.append(panelHtml);
this.htmlDoms = {
gap: this.$element.find('.verify-gap'),
sub_block: this.$element.find('.verify-sub-block'),
img_panel: this.$element.find('.verify-img-panel'),
bar_area: this.$element.find('.verify-bar-area'),
move_block: this.$element.find('.verify-move-block'),
left_bar: this.$element.find('.verify-left-bar'),
msg: this.$element.find('.verify-msg'),
icon: this.$element.find('.verify-icon'),
refresh: this.$element.find('.verify-refresh')
};
this.status = false; //鼠标状态
this.setSize = this.resetSize(this); //重新设置宽度高度
this.htmlDoms.gap.css({ 'width': this.options.blockSize.width, 'height': this.options.blockSize.height });
this.htmlDoms.sub_block.css({ 'width': this.options.blockSize.width, 'height': this.options.blockSize.height });
this.htmlDoms.img_panel.css({ 'width': this.setSize.img_width, 'height': this.setSize.img_height, 'background-size': this.setSize.img_width + ' ' + this.setSize.img_height });
this.htmlDoms.img_panel.css({ 'background': 'url(./img/' + this.options.imgName[this.img_rand] + ')' });
this.htmlDoms.bar_area.css({ 'width': this.setSize.bar_width, 'height': this.options.barSize.height, 'line-height': this.options.barSize.height });
this.htmlDoms.move_block.css({ 'width': this.options.barSize.height, 'height': this.options.barSize.height });
this.htmlDoms.left_bar.css({ 'width': this.options.barSize.height, 'height': this.options.barSize.height });
this.randSet();
},
//鼠标按下
start: function (e) {
this.htmlDoms.msg.text('');
this.htmlDoms.move_block.css('background-color', '#52ccba');
this.htmlDoms.left_bar.css('border-color', '#52ccba');
this.htmlDoms.icon.css('color', '#fff');
e.stopPropagation();
this.status = true;
$('.verify-img-panel').show();
$('.verify-sub-block').show();
if (this.defaults.num == 1) {
this.refresh();
this.defaults.num += 1;
}
},
//鼠标移动
move: function (e) {
if (this.status) {
if (!e.touches) { //兼容移动端
var x = e.clientX;
} else { //兼容PC端
var x = e.touches[0].pageX;
}
var bar_area_left = Slide.prototype.getLeft(this.htmlDoms.bar_area[0]);
var move_block_left = x - bar_area_left; //小方块相对于父元素的left值
if (this.options.type != 1) { //图片滑动
if (move_block_left >= this.htmlDoms.bar_area[0].offsetWidth - parseInt(parseInt(this.options.blockSize.width) / 2) - 2) {
move_block_left = this.htmlDoms.bar_area[0].offsetWidth - parseInt(parseInt(this.options.blockSize.width) / 2) - 2;
}
} else { //普通滑动
if (move_block_left >= this.htmlDoms.bar_area[0].offsetWidth - parseInt(parseInt(this.options.barSize.height) / 2) + 3) {
this.$element.find('.verify-msg:eq(1)').text('松开验证');
move_block_left = this.htmlDoms.bar_area[0].offsetWidth - parseInt(parseInt(this.options.barSize.height) / 2) + 3;
} else {
this.$element.find('.verify-msg:eq(1)').text('');
}
}
if (move_block_left <= 0) {
move_block_left = parseInt(parseInt(this.options.blockSize.width) / 2);
}
//拖动后小方块的left值
this.htmlDoms.move_block.css('left', move_block_left - parseInt(parseInt(this.options.blockSize.width) / 2) + "px");
this.htmlDoms.left_bar.css('width', move_block_left - parseInt(parseInt(this.options.blockSize.width) / 2) + "px");
}
},
//鼠标松开
end: function () {
var _this = this;
//判断是否重合
if (this.status) {
if (this.options.type != 1) { //图片滑动
var vOffset = parseInt(this.options.vOffset);
if (parseInt(this.htmlDoms.gap.css('left')) >= (parseInt(this.htmlDoms.move_block.css('left')) - vOffset) && parseInt(this.htmlDoms.gap.css('left')) <= (parseInt(this.htmlDoms.move_block.css('left')) + vOffset)) {
this.htmlDoms.move_block.css('background-color', '#52ccba');
this.htmlDoms.left_bar.css({ 'border-color': '#52ccba', 'background-color': '#d2f4ef' });
this.htmlDoms.icon.css('color', '#fff');
this.htmlDoms.icon.removeClass('icon-right');
this.htmlDoms.icon.addClass('icon-check');
this.htmlDoms.refresh.hide();
this.htmlDoms.move_block.unbind('mousedown touchstart');
this.options.success();
$('.verify-img-panel').hide();
$('.verify-sub-block').hide();
this.defaults.num = 1;
} else {
this.refresh();
this.htmlDoms.move_block.css('background-color', '#d9534f');
this.htmlDoms.left_bar.css('border-color', '#d9534f');
this.htmlDoms.icon.css('color', '#fff');
this.htmlDoms.icon.removeClass('icon-right');
this.htmlDoms.icon.addClass('icon-close');
setTimeout(function () {
_this.htmlDoms.move_block.animate({ 'left': '0px' }, 'fast');
_this.htmlDoms.left_bar.animate({ 'width': '40px' }, 'fast');
_this.htmlDoms.left_bar.css({ 'border-color': '#ddd' });
_this.htmlDoms.move_block.css('background-color', '#fff');
_this.htmlDoms.icon.css('color', '#000');
_this.htmlDoms.icon.removeClass('icon-close');
_this.htmlDoms.icon.addClass('icon-right');
_this.$element.find('.verify-msg:eq(0)').text('向右滑动完成验证');
}, 400);
this.options.error();
}
} else { //普通滑动
if (parseInt(this.htmlDoms.move_block.css('left')) >= (parseInt(this.setSize.bar_width) - parseInt(this.options.barSize.height) - parseInt(this.options.vOffset))) {
this.htmlDoms.move_block.css('background-color', '#52ccba');
this.htmlDoms.left_bar.css({ 'color': '#4cae4c', 'border-color': '#52ccba', 'background-color': '#d2f4ef' });
this.htmlDoms.icon.css('color', '#fff');
this.htmlDoms.icon.removeClass('icon-right');
this.htmlDoms.icon.addClass('icon-check');
this.htmlDoms.refresh.hide();
this.htmlDoms.move_block.unbind('mousedown');
this.htmlDoms.move_block.unbind('touchstart');
this.$element.find('.verify-msg:eq(1)').text('验证成功');
this.options.success();
$('.verify-img-panel').hide();
$('.verify-sub-block').hide();
this.defaults.num = 1;
} else {
this.refresh();
this.htmlDoms.move_block.css('background-color', '#d9534f');
this.htmlDoms.left_bar.css('border-color', '#d9534f');
this.htmlDoms.icon.css('color', '#fff');
this.htmlDoms.icon.removeClass('icon-right');
this.htmlDoms.icon.addClass('icon-close');
setTimeout(function () {
_this.htmlDoms.move_block.animate({ 'left': '0px' }, 'fast');
_this.htmlDoms.left_bar.animate({ 'width': '40px' }, 'fast');
_this.htmlDoms.left_bar.css({ 'border-color': '#ddd' });
_this.htmlDoms.move_block.css('background-color', '#fff');
_this.htmlDoms.icon.css('color', '#000');
_this.htmlDoms.icon.removeClass('icon-close');
_this.htmlDoms.icon.addClass('icon-right');
_this.$element.find('.verify-msg:eq(0)').text('向右滑动解锁');
}, 400);
this.options.error();
}
}
this.status = false;
}
},
resetSize: function (obj) {
var img_width, img_height, bar_width, bar_height; //图片的宽度、高度,移动条的宽度、高度
var parentWidth = obj.$element.parent().width() || $(window).width();
var parentHeight = obj.$element.parent().height() || $(window).height();
if (obj.options.imgSize.width.indexOf('%') != -1) {
img_width = parseInt(obj.options.imgSize.width) / 100 * parentWidth + 'px';
} else {
img_width = obj.options.imgSize.width;
}
if (obj.options.imgSize.height.indexOf('%') != -1) {
img_height = parseInt(obj.options.imgSize.height) / 100 * parentHeight + 'px';
} else {
img_height = obj.options.imgSize.height;
}
if (obj.options.barSize.width.indexOf('%') != -1) {
bar_width = parseInt(obj.options.barSize.width) / 100 * parentWidth + 'px';
} else {
bar_width = obj.options.barSize.width;
}
if (obj.options.barSize.height.indexOf('%') != -1) {
bar_height = parseInt(obj.options.barSize.height) / 100 * parentHeight + 'px';
} else {
bar_height = obj.options.barSize.height;
}
return { img_width: img_width, img_height: img_height, bar_width: bar_width, bar_height: bar_height };
},
//随机出生点位
randSet: function () {
var rand1 = Math.floor(Math.random() * 9 + 1);
var rand2 = Math.floor(Math.random() * 9 + 1);
var top = rand1 * parseInt(this.setSize.img_height) / 15 + parseInt(this.setSize.img_height) * 0.1;
var left = rand2 * parseInt(this.setSize.img_width) / 15 + parseInt(this.setSize.img_width) * 0.1;
this.$element.find('.verify-img-panel').css('margin-bottom', this.options.vSpace + 'px');
this.$element.find('.verify-gap').css({ 'top': top, 'left': left });
this.$element.find('.verify-sub-block').css({ 'top': '-' + (parseInt(this.setSize.img_height) - top + this.options.vSpace + 2) + 'px', 'background-image': 'url(./img/' + this.options.imgName[this.img_rand] + ')', 'background-size': this.setSize.img_width + ' ' + this.setSize.img_height, 'background-position-y': '-' + top + 'px', 'background-position-x': '-' + left + 'px' });
},
//刷新
refresh: function () {
this.randSet();
this.img_rand = Math.floor(Math.random() * this.options.imgName.length); //随机的背景图片
this.$element.find('.verify-img-panel').css({ 'background': 'url(./img/' + this.options.imgName[this.img_rand] + ')', 'background-size': this.setSize.img_width + ' ' + this.setSize.img_height });
this.$element.find('.verify-sub-block').css({ 'background-image': 'url(./img/' + this.options.imgName[this.img_rand] + ')', 'background-size': this.setSize.img_width + ' ' + this.setSize.img_height });
},
//获取left值
getLeft: function (node) {
var left = $(node).offset().left;
return left;
}
};
//在插件中使用slideVerify对象
$.fn.slideVerify = function (options, callbacks) {
var slide = new Slide(this, options);
slide.init();
};
})(jQuery, window, document);
</script>
</body>
</html>
3、css代码
/*常规验证码*/
.verify-code {
font-size: 20px;
text-align: center;
cursor: pointer;
margin-bottom: 5px;
border: 1px solid #ddd;
}
.cerify-code-panel {
height:100%;
overflow:hidden;
}
.verify-code-area {
float:left;
}
.verify-input-area {
float: left;
width: 60%;
padding-right: 10px;
}
.verify-change-area {
line-height: 30px;
float: left;
}
.varify-input-code {
display:inline-block;
width: 100%;
height: 25px;
}
.verify-change-code {
color: #337AB7;
cursor: pointer;
}
.verify-btn {
width: 200px;
height: 30px;
background-color: #337AB7;
color:#FFFFFF;
border:none;
margin-top: 10px;
}
/*滑动验证码*/
.verify-bar-area {
position: relative;
background: #FFFFFF;
text-align: center;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
border: 1px solid #ddd;
-webkit-border-radius: 4px;
}
.verify-bar-area .verify-move-block {
position: absolute;
top: 0px;
left: 0;
background: #fff;
cursor: pointer;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
box-shadow: 0 0 2px #888888;
-webkit-border-radius: 1px;
}
.verify-bar-area .verify-move-block:hover {
background-color: #1991fa;
color: #FFFFFF;
}
.verify-bar-area .verify-left-bar {
position: absolute;
top: -1px;
left: -1px;
background: #f0fff0;
cursor: pointer;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
border: 1px solid #ddd;
}
.verify-img-panel {
margin:0;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
border: 1px solid #ddd;
border-radius: 3px;
position: relative;
display: none;
position: absolute;
top: -207px;
z-index: 2;
}
.verify-img-panel .verify-refresh {
width: 25px;
height: 25px;
text-align:center;
padding: 5px;
cursor: pointer;
position: absolute;
top: -6px;
right: 9px;
z-index: 2;
}
.verify-img-panel .icon-refresh {
font-size: 20px;
color: #fff;
}
.verify-img-panel .verify-gap {
background-color: #fff;
position: relative;
z-index: 2;
border:1px solid #fff;
}
.verify-bar-area .verify-move-block .verify-sub-block {
position: absolute;
text-align: center;
z-index: 3;
border: 1px solid #fff;
display: none;
}
.verify-bar-area .verify-move-block .verify-icon {
font-size: 18px;
display: none;
}
.verify-bar-area .verify-msg {
z-index : 3;
}
/*字体图标的css*/
@font-face {font-family: "iconfont";
src: url('./fontsiconfont.eot?t=1508229193188'); /* IE9*/
src: url('./fontsiconfont.eot?t=1508229193188#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'),
url('./fontsiconfont.ttf?t=1508229193188') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('./fontsiconfont.svg?t=1508229193188#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family:"iconfont" !important;
font-size:16px;
font-style:normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-check:before { content: "\e645"; }
.icon-close:before { content: "\e646"; }
.icon-right:before { content: "\e6a3"; }
.icon-refresh:before { content: "\e6a4"; }
ps:此插件可运用到基于任何库的项目中,我已经在react项目中使用了此插件,效果一样。