溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Javascript如何實(shí)現(xiàn)登錄框拖拽效果

發(fā)布時(shí)間:2021-10-08 09:34:51 來源:億速云 閱讀:153 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹了Javascript如何實(shí)現(xiàn)登錄框拖拽效果,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

具體內(nèi)容如下

需求分析

1、點(diǎn)擊彈出登錄框

Javascript如何實(shí)現(xiàn)登錄框拖拽效果

2、在登錄框的特定區(qū)域可以將登錄框拖拽至任意位置

Javascript如何實(shí)現(xiàn)登錄框拖拽效果

3、可以關(guān)閉登錄框,并且下一次點(diǎn)擊彈出登錄框歸位

Javascript如何實(shí)現(xiàn)登錄框拖拽效果

具體實(shí)現(xiàn)

完整代碼

<!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>
        * {
            padding: 0;
            margin: 0;
        }
        a {
            text-decoration: none;
            color: black;
        }
        .login-header {
           /*  margin: 0 auto; */ /* 必須設(shè)置width才能起作用 */
            height: 30px;
            line-height: 30px;
            font-size: 24px;
            text-align: center;
        }
        .login {
            width: 500px;
            height: 300px;
            position: absolute;
            border: #725252 solid 1px;
           /*  transform: translate(-50%,-50%); */
            left: 50%;
            top: 50%;
            /* 這里不能有margin,因?yàn)槲覀冎桓淖兞薼eft和right 的只,當(dāng)移動(dòng)過后 margin還會(huì)再次生效導(dǎo)致失敗 */
           /*  margin-left: -250px;
            margin-top: 50px; */
            background-color: seashell;
            transform: translate(-50%, -50%);
            z-index: 9999;
            box-shadow: 0 0 30px black;
            display: none;
            
        }
        .login-title {
            position: relative;
            margin: 20px 0 0 0;
            height: 40px;
            line-height: 40px;
            text-align: center;
            font-size: 20px;
            cursor: move;
        }
        .close-btn {
            position: absolute;
            width: 30px;
            height: 30px;
            right: -15px;
            top: -35px;
            border-radius: 50%;
            background-color: #ffffff;
            line-height: 30px;
        }
        .login-content{
            margin: 15px auto;
            width: 450px;
            height: 230px;
        }
        .login-input label{
            margin-top: 20px;
            margin-left: 30px;
            width: 100px;
            text-align: right;
            height: 30px;
            line-height: 30px;
            display: inline-block;
        }
        .login-input input {
            height: 30px;
            width: 230px;
            border-radius: 10px;
            border: 1px solid rgba(0, 0, 0, .5);
        }
        .login-btn {
            width: 100px;
            height: 50px;
            margin: 30px auto;
            border: 1px solid black;
            border-radius: 7px;
            line-height: 50px;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="login-header"><a href="javascript:;" >登錄彈出登錄框</a></div>
    <div class="login">
        <div class="login-title">登錄
            <span><a href="javascript:;" class="close-btn">x</a></span>
        </div>
        <div class="login-content">
                <div class="login-input">
                    <label for="name">賬號(hào):</label>
                    <input type="text" id="name">
                </div>
                <div class="login-input">
                    <label for="pwd">登錄密碼:</label>
                    <input type="password" id="pwd">
                </div>
                <div class="login-btn">登錄</div>
        </div>
    </div>
    <script>
        let out = document.querySelector('.login-header');
        let login_box = document.querySelector('.login');
        let title = document.querySelector('.login-title');
        let close = document.querySelector('.close-btn');
        let move = document.querySelector('.login-content');
        out.addEventListener('click',function() {
            login_box.style.display = 'block';
        });
        close.addEventListener('click',function () {
            login_box.style.left = 50 + '%';
                login_box.style.top = 50 + '%' ;
            login_box.style.display = 'none';
        });
        /* 只有title可以移動(dòng) */
        title.addEventListener('mousedown',function(e) {
            /* 按下鼠標(biāo)的一瞬間計(jì)算出鼠標(biāo)在title中的距離,并在下一次按下鼠標(biāo)前保持不變 */
            /* 這里必須要用login_box的offset,因?yàn)樵趖itle之前已經(jīng)有絕對(duì)定位的login_box了,它的offset都為0 */
            let mousex = e.pageX - login_box.offsetLeft;
            let mousey = e.pageY - login_box.offsetTop;
            console.log(mousex,mousey);
            /* 這里為什么用的是doucument而不用title原因是鼠標(biāo)可能移動(dòng)過快超出了title的范圍,還有就是防止title盒子被遮擋,鼠標(biāo)不在title上面從前無法觸發(fā)移動(dòng)和取消事假,從而不能失效 */
            function movee(e) {
                login_box.style.left = e.pageX - mousex + 'px';
                login_box.style.top = e.pageY - mousey + 'px' ;
                
            }
            document.addEventListener('mousemove',movee)
            document.addEventListener('mouseup',function () {
                
                document.removeEventListener('mousemove',movee)
            })
        });
    
    </script>
</body>
</html>

點(diǎn)擊彈出登錄框的實(shí)現(xiàn)方式

使用JavaScript的點(diǎn)擊事件,當(dāng)點(diǎn)擊彈出時(shí)將登錄框的display設(shè)置未block即可

out.addEventListener('click',function() {
            login_box.style.display = 'block';
        });

拖拽效果的實(shí)現(xiàn)

拖拽效果的實(shí)現(xiàn)分為三個(gè)步驟:

  • 鼠標(biāo)按下,獲取鼠標(biāo)在登陸框中的坐標(biāo)

  • 鼠標(biāo)移動(dòng),獲取登陸框移動(dòng)的位置

  • 松開鼠標(biāo),解除鼠標(biāo)移動(dòng)的事件

1.鼠標(biāo)按下,獲取鼠標(biāo)在登陸框中的坐標(biāo)

如何獲得鼠標(biāo)在登陸框中的位置呢? 在這里我們使用頁面中鼠標(biāo)的坐標(biāo)減去登錄框上左邊距的方法.

Javascript如何實(shí)現(xiàn)登錄框拖拽效果

由上圖可得到,鼠標(biāo)在登陸框內(nèi)的坐標(biāo)未:( x , y ) = ( p a g e X ? o f f s e t L e f t , P a g e Y ? o f f s e t T o p ) (x,y) = (pageX - offsetLeft, PageY - offsetTop)(x,y)=(pageX?offsetLeft,PageY?offsetTop)
當(dāng)讓在這里是沒有考慮邊框?qū)ffset的影響.

/* 按下鼠標(biāo)的一瞬間計(jì)算出鼠標(biāo)在title中的距離,并在下一次按下鼠標(biāo)前保持不變 */
/* 這里必須要用login_box的offset,因?yàn)樵趖itle之前已經(jīng)有絕對(duì)定位的login_box了,它的offset都為0 */
let mousex = e.pageX - login_box.offsetLeft;
let mousey = e.pageY - login_box.offsetTop;

2.鼠標(biāo)移動(dòng),獲取登錄框的位置

這時(shí)候鼠標(biāo)在登錄框的位置在鼠標(biāo)松開之前是不會(huì)在變化的,我們可以利用這個(gè)特性來得到當(dāng)前登錄框的位置。那就是鼠標(biāo)在頁面中的坐標(biāo)減去鼠標(biāo)在頁面中的坐標(biāo)即可。這里就不再做過多的解釋了。

/* 這里為什么用的是doucument而不用title原因是鼠標(biāo)可能移動(dòng)過快超出了title的范圍,還有就是防止title盒子被遮擋,鼠標(biāo)不在title上面從前無法觸發(fā)移動(dòng)和取消事假,從而不能失效 */
            function movee(e) {
                login_box.style.left = e.pageX - mousex + 'px';
                login_box.style.top = e.pageY - mousey + 'px' ;
                
            }
            document.addEventListener('mousemove',movee)

3.松開鼠標(biāo),解除鼠標(biāo)移動(dòng)的事件

document.addEventListener('mouseup',function () {
                document.removeEventListener('mousemove',movee)
            })

關(guān)閉登錄框,位置歸位

將其display設(shè)置為none即可,具體看代碼。

close.addEventListener('click',function () {
            login_box.style.left = 50 + '%';
            login_box.style.top = 50 + '%' ;
            login_box.style.display = 'none';
        });

效果展示

Javascript如何實(shí)現(xiàn)登錄框拖拽效果

代碼實(shí)現(xiàn)時(shí)遇到的困難

1、使用margin居中時(shí)必須要有width,好久沒寫代碼了都有點(diǎn)忘記了。
2、因?yàn)榻o登錄框設(shè)置了margin導(dǎo)致移動(dòng)錯(cuò)位,這是因?yàn)槲业淖鴺?biāo)計(jì)算公式是沒有考慮margin的(只考慮了定位的leftright),導(dǎo)致登錄框到達(dá)了坐標(biāo)位置又因?yàn)?strong>magin又調(diào)整了位置。解決的方法應(yīng)該時(shí)在計(jì)算移動(dòng)的坐標(biāo)時(shí)減去margin即可。
3、offset是相對(duì)了有定位的父級(jí)節(jié)點(diǎn)來說的,要牢記。
4、為什么鼠標(biāo)移動(dòng)時(shí)是對(duì)document綁定的事件?

為了放置鼠標(biāo)移動(dòng)過快時(shí)間無法正確處理所以事件綁定到document上。若這個(gè)登錄框沒有加絕對(duì)定位,那么在移動(dòng)的過程中可能會(huì)被其他的元素遮擋,所以移動(dòng)事件不能綁定在登錄框上,而是綁定在document上。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Javascript如何實(shí)現(xiàn)登錄框拖拽效果”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

js
AI