欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript實(shí)現(xiàn)登錄拼圖驗(yàn)證的示例代碼

 更新時(shí)間:2023年01月11日 15:28:09   作者:小孔菜菜  
這篇文章主要為大家詳細(xì)介紹了如何利用JavaScript實(shí)現(xiàn)登錄拼圖驗(yàn)證的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

看到一個(gè)好文,所以模仿這實(shí)現(xiàn)一個(gè)登錄時(shí)的拼圖驗(yàn)證。效果展示如下。

底圖實(shí)現(xiàn)

首先實(shí)現(xiàn)一個(gè)盒子,存放我的

// html
        <div class="check">
        </div>
// css
    .check {
            width: 400px;
            height: 300px;
            background-image: url(./img/bg.avif);
            background-size: 100% 100%;
            background-repeat: no-repeat;
            position: relative;
            filter: brightness(80%);
    }

底圖中的驗(yàn)證區(qū)域通過偽類實(shí)現(xiàn)

    .check::before {
            position: absolute;
            content: '';
            width: 50px;
            height: 50px;
            background: rgba(0, 0, 0, 0.5);
            top: 100px;
            left: 280px;
    }

被驗(yàn)證區(qū)域塊

被驗(yàn)證區(qū)域有點(diǎn)類似于摳圖的概念了,通過從底圖中截取一部分,并且改變放置的位置,使其看起來是整體的一部分。核心的思想就是利用了background-position設(shè)置負(fù)值,獲取圖片的部分

        <div class="check">
                <!-- 驗(yàn)證區(qū)塊通過偽類實(shí)現(xiàn) -->
                <!-- 被驗(yàn)證區(qū)塊 -->
                <div class="check-box" id="check-box"></div>
        </div>
        .check-box {
                width: 50px;
                height: 50px;
                position: absolute;
                top: 100px;
                left: 0;
                background-image: inherit;
                background-repeat: inherit;
                background-size: 400px 300px;
                background-position: -280px -100px;
                border: 1px solid #fff;
        }

滑塊區(qū)域

滑塊的html+css實(shí)現(xiàn)特別簡單,這里有一個(gè)對(duì)號(hào)是通過border-width實(shí)現(xiàn)的,感覺很妙呀!

    <!-- 拖動(dòng)條 -->
    <div class="drag">
            <!-- 滑塊 -->
            <div class="drag-box" id="drag-box">
                    <!-- 對(duì)號(hào) -->
                    <div id="drag-mark" class="drag-mark"></div>
            </div>
            <!-- 文字提示 -->
            <div class="drag-tips">
                    <span>按住左邊按鈕向右拖動(dòng)完成上方圖像驗(yàn)證</span>
            </div>
    </div>
    .drag {
            width: 400px;
            height: 50px;
            background-color: #e3e3e3;
            margin-top: 10px;
            position: relative;
    }
    .drag-box {
            position: absolute;
            top: 0;
            left: 0;
            width: 50px;
            height: 50px;
            background-color: aquamarine;
            z-index: 10;
            display: flex;
            justify-content: center;
            align-items: center;
    }
    .drag-tips {
            position: absolute;
            top: 0;
            left: 0;
            display: flex;
            justify-content: end;
            align-items: center;
            width: 95%;
            height: 100%;
            font-size: 12px;
            color: #8a8a8a;
            user-select: none;
    }
    .drag-mark {
            width: 8px;
            height: 16px;
            border-color: #009933;
            border-style: solid;
            border-width: 0 3px 5px 0;
            transform: rotate(45deg);
            opacity: 0;
            transition: 0.3s;
    }

動(dòng)態(tài)滑動(dòng)

滑動(dòng)的過程涉及鼠標(biāo)按下、鼠標(biāo)移動(dòng)、鼠標(biāo)彈起

鼠標(biāo)按下

保存鼠標(biāo)的初始水平值pageX,方便下一步計(jì)算移動(dòng)值

監(jiān)聽鼠標(biāo)的移動(dòng)事件

    // 鼠標(biāo)按下
    const mouseDown = (event) => {
            // 獲取鼠標(biāo)坐標(biāo)
            preX = event.pageX
            // 監(jiān)聽鼠標(biāo)移動(dòng)
            document.addEventListener('mousemove', mouseMove)
    }
···

鼠標(biāo)移動(dòng)

  • 獲取當(dāng)前的鼠標(biāo)值pageX,和原始值做減法,得到移動(dòng)值
  • 移除監(jiān)聽鼠標(biāo)的移動(dòng)事件
  • 設(shè)置滑塊和被驗(yàn)證區(qū)域塊的移動(dòng)值

思考:這里使用pageX,clientX都可以實(shí)現(xiàn)相應(yīng)的效果,但是使用offsetX的時(shí)候會(huì)出現(xiàn)閃爍的效果,看到很多帖子說使用pointer-events: none解決,我的不可以,留一個(gè)疑問在這里吧:鼠標(biāo)的移動(dòng)值到底怎么計(jì)算?,等日后參悟透了再來更新。

    // 鼠標(biāo)移動(dòng)
    const mouseMove = (event) => {
            const { pageX } = event
            // 移動(dòng)距離
            const moveX = pageX - preX
            // 移動(dòng)不能超出區(qū)域
            if (moveX < 0 || moveX > 350) {
                    return
            }
            check.style.transform = `translateX(${moveX}px)`
            drag.style.transform = `translateX(${moveX}px)`
    }

鼠標(biāo)抬起

  • 獲取當(dāng)前的鼠標(biāo)值pageX,和原始值做減法,得到移動(dòng)值
  • 判斷移動(dòng)值是否在有效區(qū)間之內(nèi)
  • 在有效區(qū)間,調(diào)用驗(yàn)證通過的回調(diào)函數(shù)
  • 不在有效區(qū)間,應(yīng)該給滑塊和被驗(yàn)證區(qū)域塊設(shè)計(jì)回彈動(dòng)畫的效果
        // 鼠標(biāo)抬起
        const mouseUp = (event) => {
                // 移出移動(dòng)事件
                document.removeEventListener('mousemove', mouseMove)
                const { pageX } = event
                const moveX = pageX - preX
                if (moveX < 278 || moveX > 285) {
                .......
                } else {
                        success()
                }
        }

有效驗(yàn)證

有效驗(yàn)證是指驗(yàn)證通過的回調(diào)函數(shù)

    // 校驗(yàn)回調(diào)函數(shù)
    const success = () => {
            console.log('通過校驗(yàn)!')
    }

動(dòng)畫處理

對(duì)于回彈動(dòng)畫的處理,首先是css方面,設(shè)計(jì)動(dòng)畫效果,然后是js方面,滑塊和被驗(yàn)證區(qū)域賦值動(dòng)畫效果,監(jiān)聽動(dòng)畫結(jié)束事件,動(dòng)畫結(jié)束的時(shí)候,滑塊和被驗(yàn)證區(qū)域回到0的位置,清除動(dòng)畫效果。

    /* 回彈動(dòng)畫 */
    @keyframes move {
            to {
                    transform: translateX(0);
            }
    }
    if (moveX < 278 || moveX > 285) {
            // 沒有在校驗(yàn)區(qū)域 增加回彈動(dòng)畫
            drag.style.animation = 'move 0.5s ease-in-out'
            check.style.animation = 'move 0.5s ease-in-out'
            // 動(dòng)畫結(jié)束回調(diào)
            const animationEnd = () => {
                    check.style.transform = `translateX(${0}px)`
                    drag.style.transform = `translateX(${0}px)`
                    mark.style.opacity = 0
                    // 清除動(dòng)畫
                    drag.style.animation = ''
                    check.style.animation = ''
                    // 取消監(jiān)聽動(dòng)畫結(jié)束回調(diào)
                    document.removeEventListener('animationEnd', animationEnd)
            }
            document.addEventListener('animationend', animationEnd)
    }

完整代碼

圖片是遠(yuǎn)程服務(wù)器上的,我下載到本地了,點(diǎn)擊上面的底圖鏈接可以獲取到原圖。

<!--
 * @Author: Kongjingjing
 * @Date: 2023-01-10 15:37:03
 * @Description: 
-->
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Document</title>
		<style>
			.check {
				width: 400px;
				height: 300px;
				background-image: url(./img/bg.avif);
				background-size: 100% 100%;
				background-repeat: no-repeat;
				position: relative;
				filter: brightness(80%);
			}
			.check::before {
				position: absolute;
				content: '';
				width: 50px;
				height: 50px;
				background: rgba(0, 0, 0, 0.5);
				top: 100px;
				left: 280px;
			}
			.check-box {
				width: 50px;
				height: 50px;
				position: absolute;
				top: 100px;
				left: 0;
				background-image: inherit;
				background-repeat: inherit;
				background-size: 400px 300px;
				background-position: -280px -100px;
				border: 1px solid #fff;
			}
			.drag {
				width: 400px;
				height: 50px;
				background-color: #e3e3e3;
				margin-top: 10px;
				position: relative;
			}
			.drag-box {
				position: absolute;
				top: 0;
				left: 0;
				width: 50px;
				height: 50px;
				background-color: aquamarine;
				z-index: 10;
				display: flex;
				justify-content: center;
				align-items: center;
			}
			.drag-tips {
				position: absolute;
				top: 0;
				left: 0;
				display: flex;
				justify-content: end;
				align-items: center;
				width: 95%;
				height: 100%;
				font-size: 12px;
				color: #8a8a8a;
				user-select: none;
			}
			/* 回彈動(dòng)畫 */
			@keyframes move {
				to {
					transform: translateX(0);
				}
			}
			.drag-mark {
				width: 8px;
				height: 16px;
				border-color: #009933;
				border-style: solid;
				border-width: 0 3px 5px 0;
				transform: rotate(45deg);
				opacity: 0;
				transition: 0.3s;
			}
		</style>
	</head>
	<body>
		<div class="check">
			<!-- 驗(yàn)證區(qū)塊通過偽類實(shí)現(xiàn) -->
			<!-- 被驗(yàn)證區(qū)塊 -->
			<div class="check-box" id="check-box"></div>
		</div>
		<!-- 拖動(dòng)條 -->
		<div class="drag">
			<!-- 滑塊 -->
			<div class="drag-box" id="drag-box">
				<!-- 對(duì)號(hào) -->
				<div id="drag-mark" class="drag-mark"></div>
			</div>
			<!-- 文字提示 -->
			<div class="drag-tips">
				<span>按住左邊按鈕向右拖動(dòng)完成上方圖像驗(yàn)證</span>
			</div>
		</div>
	</body>
	<script>
		// 被驗(yàn)證區(qū)塊
		const check = document.getElementById('check-box')
		// 滑塊
		const drag = document.getElementById('drag-box')
		// 對(duì)號(hào)
		const mark = document.getElementById('drag-mark')
		let preX = 0
		// 鼠標(biāo)按下
		const mouseDown = (event) => {
			// 獲取鼠標(biāo)坐標(biāo)
			preX = event.pageX
			// 監(jiān)聽鼠標(biāo)移動(dòng)
			document.addEventListener('mousemove', mouseMove)
		}
		// 鼠標(biāo)移動(dòng)
		const mouseMove = (event) => {
			const { pageX } = event
			// 移動(dòng)距離
			const moveX = pageX - preX
			// 移動(dòng)不能超出區(qū)域
			if (moveX < 0 || moveX > 350) {
				return
			}
			check.style.transform = `translateX(${moveX}px)`
			drag.style.transform = `translateX(${moveX}px)`
		}
		// 鼠標(biāo)抬起
		const mouseUp = (event) => {
			// 移出移動(dòng)事件
			document.removeEventListener('mousemove', mouseMove)
			const { pageX } = event
			const moveX = pageX - preX
			if (moveX < 278 || moveX > 285) {
				// 沒有在校驗(yàn)區(qū)域 增加回彈動(dòng)畫
				drag.style.animation = 'move 0.5s ease-in-out'
				check.style.animation = 'move 0.5s ease-in-out'
				// 動(dòng)畫結(jié)束回調(diào)
				const animationEnd = () => {
					check.style.transform = `translateX(${0}px)`
					drag.style.transform = `translateX(${0}px)`
					mark.style.opacity = 0
					// 清除動(dòng)畫
					drag.style.animation = ''
					check.style.animation = ''
					// 取消監(jiān)聽動(dòng)畫結(jié)束回調(diào)
					document.removeEventListener('animationEnd', animationEnd)
				}
				document.addEventListener('animationend', animationEnd)
			} else {
				// 對(duì)號(hào)
				mark.style.opacity = 1
				success()
			}
		}
		// 校驗(yàn)回調(diào)函數(shù)
		const success = () => {
			console.log('通過校驗(yàn)!')
		}
		// 滑塊綁定鼠標(biāo)按下事件
		drag.addEventListener('mousedown', mouseDown)
		document.addEventListener('mouseup', mouseUp)
	</script>
</html>

到此這篇關(guān)于JavaScript實(shí)現(xiàn)登錄拼圖驗(yàn)證的示例代碼的文章就介紹到這了,更多相關(guān)JavaScript登錄拼圖驗(yàn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論