slider滑块,验证登录滑块
SlideToUnLock� 滑动验证
import React, { useEffect, useRef, useState, forwardRef, useImperativeHandle } from "react";
import { func, number } from "prop-types";
import styles from "./style.module.less";
const SlideToUnLockRef = forwardRef(SlideToUnLock);
SlideToUnLockRef.propTypes = {
onChange: func.isRequired,
height: number
};
SlideToUnLockRef.defaultProps = {
height: 32,
onChange: () => {}
};
export default SlideToUnLockRef
function SlideToUnLock({ height, onChange }, ref) {
const rootRef = useRef();
// 滑块
const slideRef = useRef(null);
// 文字
const textRef = useRef("");
// 背景颜色
const bgRef = useRef(null);
const [title, setTitle] = useState("拖动滑块验证");
useEffect(init, []);
useImperativeHandle(ref, () => ({
reset: () => {},
}))
function init() {
if (!rootRef.current) {
return console.error("没有找到 slide DOM");
}
const MOVE_WIDTH = rootRef.current.offsetWidth - slideRef.current.offsetWidth; // 可以移动的距离
// 触发事件 onmousedown按下 onmousemove移动 onmouseup松开
slideRef.current.onmousedown = (e) => {
// e.clientX 鼠标点的位置
onMouseMove(e.clientX);
};
// 鼠标松开时
document.onmouseup = () => {
if (parseInt(slideRef.current.style.left) === MOVE_WIDTH) return;
// 松开后回到原点,清除移动事件
slideRef.current.style.left = 0;
bgRef.current.style.width = 0;
document.onmousemove = null;
textRef.current.classList.remove(styles.white);
};
// 拖拽移动时发生
function onMouseMove(clientX) {
document.onmousemove = (e) => {
e.preventDefault();
// 移动的X轴坐标 = 当前的 clientX - 之前鼠标的 clientX
const moveX = e.clientX - clientX;
// 可移动的范围 = 总宽度 - 按钮的宽度
if (moveX >= 0 && moveX <= MOVE_WIDTH) {
slideRef.current.style.left = moveX + "px"; // 滑块绝对定位
bgRef.current.style.width = (moveX + 20) + "px"; // 设备背景的宽度
if (moveX > MOVE_WIDTH / 2) {
textRef.current.classList.add(styles.white);
}
}
// 验证成功
if (moveX >= MOVE_WIDTH) {
slideRef.current.style.left = MOVE_WIDTH + "px"; // 滑块绝对定位
bgRef.current.style.width = (MOVE_WIDTH + 20) + "px"; // 设备背景的宽度
setTitle("验证成功");
onChange(true);
// 事件清除-按下、移动
slideRef.current.onmousedown = null;
slideRef.current.onmouseup = null;
document.onmousemove = null;
}
};
}
}
return (
<div
ref={rootRef}
className='relative flex items-center bg-slate-50 select-none rounded-md'
style={{ height }}
>
{/*滑块*/}
<div
ref={slideRef}
className={`h-full rounded-md absolute z-30 border-box ${styles.slide}`}
/>
{/*拖动滑块验证文本*/}
<span
ref={textRef}
className={`text-xs text-slate-500 absolute z-20 bg-transparent ${styles.title}`}
>
{title}
</span>
{/*背景颜色*/}
<span
ref={bgRef}
className={`h-full rounded-l-md absolute z-10 ${styles.success}`}
/>
</div>
);
}
图片滑动拼图验证
https://blog.csdn.net/weixin_33729196/article/details/88624323
滑块验证
https://codepen.io/souporserious/pen/XJQLEb
https://gitee.com/mycssweb/react-simple-verify