slider滑块,验证登录滑块

SlideToUnLock� 滑动验证

image.png

  1. import React, { useEffect, useRef, useState, forwardRef, useImperativeHandle } from "react";
  2. import { func, number } from "prop-types";
  3. import styles from "./style.module.less";
  4. const SlideToUnLockRef = forwardRef(SlideToUnLock);
  5. SlideToUnLockRef.propTypes = {
  6. onChange: func.isRequired,
  7. height: number
  8. };
  9. SlideToUnLockRef.defaultProps = {
  10. height: 32,
  11. onChange: () => {}
  12. };
  13. export default SlideToUnLockRef
  14. function SlideToUnLock({ height, onChange }, ref) {
  15. const rootRef = useRef();
  16. // 滑块
  17. const slideRef = useRef(null);
  18. // 文字
  19. const textRef = useRef("");
  20. // 背景颜色
  21. const bgRef = useRef(null);
  22. const [title, setTitle] = useState("拖动滑块验证");
  23. useEffect(init, []);
  24. useImperativeHandle(ref, () => ({
  25. reset: () => {},
  26. }))
  27. function init() {
  28. if (!rootRef.current) {
  29. return console.error("没有找到 slide DOM");
  30. }
  31. const MOVE_WIDTH = rootRef.current.offsetWidth - slideRef.current.offsetWidth; // 可以移动的距离
  32. // 触发事件 onmousedown按下 onmousemove移动 onmouseup松开
  33. slideRef.current.onmousedown = (e) => {
  34. // e.clientX 鼠标点的位置
  35. onMouseMove(e.clientX);
  36. };
  37. // 鼠标松开时
  38. document.onmouseup = () => {
  39. if (parseInt(slideRef.current.style.left) === MOVE_WIDTH) return;
  40. // 松开后回到原点,清除移动事件
  41. slideRef.current.style.left = 0;
  42. bgRef.current.style.width = 0;
  43. document.onmousemove = null;
  44. textRef.current.classList.remove(styles.white);
  45. };
  46. // 拖拽移动时发生
  47. function onMouseMove(clientX) {
  48. document.onmousemove = (e) => {
  49. e.preventDefault();
  50. // 移动的X轴坐标 = 当前的 clientX - 之前鼠标的 clientX
  51. const moveX = e.clientX - clientX;
  52. // 可移动的范围 = 总宽度 - 按钮的宽度
  53. if (moveX >= 0 && moveX <= MOVE_WIDTH) {
  54. slideRef.current.style.left = moveX + "px"; // 滑块绝对定位
  55. bgRef.current.style.width = (moveX + 20) + "px"; // 设备背景的宽度
  56. if (moveX > MOVE_WIDTH / 2) {
  57. textRef.current.classList.add(styles.white);
  58. }
  59. }
  60. // 验证成功
  61. if (moveX >= MOVE_WIDTH) {
  62. slideRef.current.style.left = MOVE_WIDTH + "px"; // 滑块绝对定位
  63. bgRef.current.style.width = (MOVE_WIDTH + 20) + "px"; // 设备背景的宽度
  64. setTitle("验证成功");
  65. onChange(true);
  66. // 事件清除-按下、移动
  67. slideRef.current.onmousedown = null;
  68. slideRef.current.onmouseup = null;
  69. document.onmousemove = null;
  70. }
  71. };
  72. }
  73. }
  74. return (
  75. <div
  76. ref={rootRef}
  77. className='relative flex items-center bg-slate-50 select-none rounded-md'
  78. style={{ height }}
  79. >
  80. {/*滑块*/}
  81. <div
  82. ref={slideRef}
  83. className={`h-full rounded-md absolute z-30 border-box ${styles.slide}`}
  84. />
  85. {/*拖动滑块验证文本*/}
  86. <span
  87. ref={textRef}
  88. className={`text-xs text-slate-500 absolute z-20 bg-transparent ${styles.title}`}
  89. >
  90. {title}
  91. </span>
  92. {/*背景颜色*/}
  93. <span
  94. ref={bgRef}
  95. className={`h-full rounded-l-md absolute z-10 ${styles.success}`}
  96. />
  97. </div>
  98. );
  99. }

图片滑动拼图验证

https://blog.csdn.net/weixin_33729196/article/details/88624323

滑块验证

https://codepen.io/souporserious/pen/XJQLEb
https://gitee.com/mycssweb/react-simple-verify
image.png