<template>
<div
class="drag"
ref="dragDiv"、
>
<div
class="drag_bg"
ref="bgRef"
>
</div>
<div
class="drag_text"
ref="textRef"
>
{{confirmWords}}
</div>
<div
ref="moveDiv"
class="handler"
:class="{'handler-success': confirmSuccess}"
@mousedown="mouseDownFn($event)"
>
<Icon
icon="lucide:chevrons-right"
class="text-[21px] text-primary"
v-if="!confirmSuccess"
>
</Icon>
<Icon
icon="ep:success-filled"
class="text-[21px] text-primary"
v-else>
</Icon>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
const confirmWords = ref<string>('向右拖动滑块验证'); // 滑块文字
const confirmSuccess = ref<boolean>(false); // 是否已经成功
const beginClientX = ref<number>(0); // 距离屏幕左端距离
const mouseMoveState = ref<boolean>(false); // 是否触发拖动状态
const maxWidth = ref<number>(0); // 拖动最大宽度
const dragDiv = ref<HTMLElement | any>(null);
const moveDiv = ref<HTMLElement | any>(null);
const bgRef = ref<HTMLElement | any>(null);
const textRef = ref<HTMLElement | any>(null);
onMounted(() => {
maxWidth.value = dragDiv.value?.clientWidth - moveDiv.value.clientWidth;
document.getElementsByTagName('html')[0].addEventListener('mousemove', mouseMoveFn);
document.getElementsByTagName('html')[0].addEventListener('mouseup', moseUpFn);
});
function mouseDownFn(e: any) {
if(!confirmSuccess.value){
e.preventDefault && e.preventDefault(); //阻止文字选中等 浏览器默认事件
mouseMoveState.value = true;
beginClientX.value = e.clientX;
}
}
function mouseMoveFn(e: any) {
if(mouseMoveState.value){
let width = e.clientX - beginClientX.value;
if (width > 0 && width <= maxWidth.value) {
moveDiv.value.style.left = width + 'px';
bgRef.value.style.width = width + 'px';
} else if (width > maxWidth.value) {
successFunction();
}
}
}
function successFunction() {
confirmSuccess.value = true;
confirmWords.value = '验证通过';
document.getElementsByTagName('html')[0].removeEventListener('mousemove', mouseMoveFn);
document.getElementsByTagName('html')[0].removeEventListener('mouseup', moseUpFn);
textRef.value.style.color = '#fff';
moveDiv.value.style.left = maxWidth.value + 'px';
bgRef.value.style.width = maxWidth.value + 'px';
}
function moseUpFn(e: any) {
mouseMoveState.value = false;
var width = e.clientX - beginClientX.value;
if(width < maxWidth.value) {
moveDiv.value.style.left = 0 + 'px';
bgRef.value.style.width = 0 + 'px';
}
}
defineExpose({
sliderSuccess: confirmSuccess
});
</script>
<style lang="less" scoped>
.drag {
position: relative;
background-color: rgba(30, 41, 59, 0.3);
width: 100%;
height: 40px;
line-height: 40px;
text-align: center;
border: 1px solid #eee;
border-radius: 6px;
color: #fff;
.drag_bg{
background-color: var(--el-color-primary);
height: 38px;
width: 0px;
border-radius: 6px 0 0 6px;
}
.drag_text {
position: absolute;
top: 0px;
width: 100%;
text-align: center;
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
-o-user-select:none;
-ms-user-select:none;
}
.handler{
width: 40px;
height: 38px;
border: 1px solid #ccc;
border-radius: 6px 0 0 6px;
cursor: pointer;
background-color: #fff;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
&:hover {
svg {
transform: scale(1.2);
transition: all 0.5s;
}
}
}
.handler-success {
border-radius: 0 6px 6px 0;
}
}
</style>