Demo登录框的可拖拽(原生、jQuery、H5托和放)三种办法实现

此处不考虑兼容性问题,因为在IE8及其以下的版本中不支持事件对象的page坐标系列。所以我们直接使用元素的page系列坐标。

一、原生JS实现
需求:
// 1.点击登录按钮,让登录盒子显示在页面上,同时出现遮罩层
// 2.点击登录盒子的关闭按钮,登录盒子消失
// 3.登录盒子可拖拽

思路分析:这里的重点是第三步登录盒子的可拖拽,具体思路如下图:
这里写图片描述

我们解决盒子拖拽的思路就是:因为红线的距离是一直不变的,所以,可以先求出来定义为x,y;而在整个页面中注册鼠标移动事件,这样就可以求出在页面上触发点的e.pageX,利用e.pageX - x 这样就可以求出盒子的offsetLeft值,这个值就是元素的left值,最后将这个值赋给元素的left属性就可以了。

当然里面有两个问题:
1.元素本身有margin属性?
2.给页面添加了一个鼠标移动事件,那么在页面上的任何位置移动,都会让login盒子可拖拽吗?

这里写图片描述

先说第一个问题:
当元素有margin属性的时候,我们如果直接将offsetLeft = e.pageX - 红线的距离赋值给元素的left属性,此时定位的left属性与margin-left的值会发生叠加计算得到一个新的值,此时才是盒子距离页面左边的位置。所以我们要将margin的值也考虑到计算进去,最后计算出来的offsetLeft的值就是盒子的真实距离。

offsetLeft = e.pageX - (-256px)(magin-left的值) - 红线的位置 ;整体赋值给left,因为页面又有:
margin-left = -256px; 所以两者叠加后就是真正的offsetLeft的值。
这里写图片描述

再说第二个问题:
2.给页面添加了一个鼠标移动事件,那么在页面上的任何位置上移动,都会让login盒子可拖拽吗?换句话说,因为在整个页面注册了onmousemove事件,那么在整个页面移动,盒子都会拖动起来吗?

肯定不是的,这是因为我们注册的事件的是又两个:
第一个:给login盒子的头部区域title,注册了一个鼠标按下事件。
第二个:在第一个事件函数的里面,又注册了一个整个页面的鼠标移动事件。

也就可以这样理解:只有我按下登录盒子的头部后,并且鼠标停留在上面,此时就可以拖动盒子在整个页面上移动。

代码实现:


<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        /* 登录按钮 */
        .login-header {
            width: 100%;
            text-align: center;
            height: 30px;
            font-size: 24px;
            line-height: 30px;
        }

        html, body, ul, li, ol, dl, dt, dd, div, p, span, h1, h2, h3, h4, h5, h6, a {
            padding: 0px;
            margin: 0px;
        }

        /* 登录盒子 */
        .login {
            width: 512px;
            position: absolute;
            border: #ebebeb solid 1px;
            height: 280px;
            left: 50%;
            right: 50%;
            background: #ffffff;
            box-shadow: 0px 0px 20px #ddd;
            z-index: 9999;
            margin-left: -256px;
            margin-top: 140px;
            /* 登录盒子的显示模式默认是不显示 */
            display: none;
        }

        .login-title {
            width: 100%;
            margin: 10px 0px 0px 0px;
            text-align: center;
            line-height: 40px;
            height: 40px;
            font-size: 18px;
            position: relative;
            cursor: move;
        }

        .login-input-content {
            margin-top: 20px;
        }

        .login-button {
            width: 50%;
            margin: 30px auto 0px auto;
            line-height: 40px;
            font-size: 14px;
            border: #ebebeb 1px solid;
            text-align: center;
        }

        /* 遮罩层的设计 */
        .login-bg {
            width: 100%;
            height: 100%;
            position: fixed;
            top: 0px;
            left: 0px;
            background: #000000;
            opacity: 0.3;
            display: none;
        }

        a {
            text-decoration: none;
            color: #000000;
        }

        .login-button a {
            display: block;
        }

        .login-input input.list-input {
            float: left;
            line-height: 35px;
            height: 35px;
            width: 350px;
            border: #ebebeb 1px solid;
            text-indent: 5px;
        }

        .login-input {
            overflow: hidden;
            margin: 0px 0px 20px 0px;
        }

        .login-input label {
            float: left;
            width: 90px;
            padding-right: 10px;
            text-align: right;
            line-height: 35px;
            height: 35px;
            font-size: 14px;
        }

        /* 登录关闭按钮 */
        .login-title span {
            position: absolute;
            font-size: 12px;
            right: -20px;
            top: -30px;
            background: #ffffff;
            border: #ebebeb solid 1px;
            width: 40px;
            height: 40px;
            border-radius: 20px;
        }
    </style>
</head>
<body>

<!-- 登录按钮 -->
<div class="login-header">
    <a id="link" href="javascript:void(0);">点击,弹出登录框</a>
</div>

<!-- 登录的盒子 -->
<div id="login" class="login">
    <div id="title" class="login-title">登录会员
        <span>
            <a id="closeBtn" href="javascript:void(0);" class="close-login"> 关闭</a>
        </span>
    </div>

    <div class="login-input-content">
        <div class="login-input">
            <label>用户名:</label>
            <input type="text" placeholder="请输入用户名" name="info[username]" id="username" class="list-input">
        </div>
        <div class="login-input">
            <label>登录密码:</label>
            <input type="password" placeholder="请输入登录密码" name="info[password]" id="password" class="list-input">
        </div>
    </div>
    <div id="loginBtn" class="login-button"><a href="javascript:void(0);" id="login-button-submit">登录会员</a></div>
</div>

<!-- 遮罩层是整个body的背景 -->
<div id="bg" class="login-bg"></div>


<script>
    //需求:
    // 1.点击登录按钮,让登录盒子显示在页面上,同时出现遮罩层
    // 2.点击登录盒子的关闭按钮,登录盒子消失
    // 3.登录盒子可拖拽

    //获取元素
    var loginBtn = document.getElementById("link"); //登录按钮
    var login = document.getElementById("login"); //登录盒子
    var closeLogin = document.getElementsByClassName("close-login")[0]; //关闭登录盒子的按钮
    var bg = document.getElementById('bg'); //遮罩层
    var title = document.getElementById('title'); //头部


    loginBtn.onclick = function(){
        //点击登录按钮的时候,弹出登录框
        login.style.display= "block";
        //打开遮罩层
        bg.style.display = "block";
    }

    closeLogin.onclick = function(){
        //点击关闭按钮,登录框隐藏
        login.style.display = "none";
        //打开遮罩层
        bg.style.display = "none";
    }

    //可以按住拖拽的部分title
    //当然也可以给整登录盒子 login盒子注册一个按下事件
    title.onmousedown = function(e){

        //1.获取红线的距离
        var x = e.pageX - login.offsetLeft;
        var y = e.pageY - login.offsetTop;

        //给整个页面添加鼠标移动事件
        document.onmousemove = function (e){ 
            //计算此时登录盒子在页面当中的位置
            login.style.left = e.pageX - x + 256 + "px";
            login.style.top = e.pageY - y - 140 + "px";
        }

    }

    title.onmouseup = function(){
        //当鼠标弹起时将页面的鼠标移动事件清空就可以了
        document.onmousemove = null;
    }

</script>

</body>
</html>

二、jQuery代码实现:

思路都是一样,只需要将上面的代码翻译为jQuery的代码来实现就可以了。

<script src="jquery-1.12.4.js"></script>
<script>
    $(function(){

        $('#link').on("click",function(){
            $('#login').show();
            $('#bg').show();
        })

        $('.close-login').on('click',function(){
            $('#login').hide();
            $('#bg').hide();
        })

        $('#title').on('mousedown',function(event){

            //计算盒子在页面上的位置
            var offset_x = $('#login').offset().left;
            var offset_y = $('#login').offset().top;
            //获取鼠标在login盒子里面的触发点
            var mouse_x = event.pageX;
            var mouse_y = event.pageY;

            $("body").on('mousemove',function(e){
                console.log(e.target);

                /* 计算鼠标移动了的位置 */
                var _x = e.pageX - mouse_x;
                var _y = e.pageY - mouse_y;

                /* 设置移动后的元素坐标 */
                //这里的256是元素自身带有的margin-left的值,下面的140同理
                var now_x = (offset_x + _x + 256 ) + "px";
                var now_y = (offset_y + _y - 140) + "px";

                $('#login').css('left',now_x);
                $('#login').css('top',now_y);

            })
        })

        $('#title').on('mouseup',function(){
            //这里利用事件的解绑
            $('body').off('mousemove');
        })
    })
</script>

利用jQuery实现的思路与JS大体相仿,这里就不多做解释.

三、利用H5里面的托和放来实现

注意:在网页中,图片可以托拽,其他的默认不能托拽。如果一定要拖拽,要在标签加上,加一个行内属性 draggable=”true”,这个属性默认是false。
以及拖拽的三个事件:

//拖拽开始触发的事件
元素.ondragstart = function () {  }

//拖拽中触发的事件
元素.ondrag = function () { }

//拖拽结束事件
box.ondragend = function () { }

利用上面的知识将登陆框的可拖拽利用H5实现:因为样式与页面结构是一模一样的,所以这里只有js的代码。

<script>

    var loginBtn = document.getElementById("link"); //登录按钮
    var closeLogin = document.getElementsByClassName("close-login")[0]; //关闭登录盒子的按钮
    var bg = document.getElementById('bg'); //遮罩层
    var title = document.getElementById('title'); //头部
    //利用H5的托和放来实现登录盒子的拖拽功能
    var login = document.getElementById("login"); //登录盒子
    //定义x,y来保存鼠标在盒子里的位置
    var x,y;


    loginBtn.onclick = function(){
        //点击登录按钮的时候,弹出登录框
        login.style.display= "block";
        //打开遮罩层
        bg.style.display = "block";
    }

    closeLogin.onclick = function(){
        //点击关闭按钮,登录框隐藏
        login.style.display = "none";
        //打开遮罩层
        bg.style.display = "none";
    }

    //盒子拖拽开始事件
    login.ondragstart = function(e) {

        //获取鼠标在盒子里面的位置
        x = e.pageX - login.offsetLeft;
        y = e.pageY - login.offsetTop;

        // login.style.cursor = "crosshair";
    }

    //盒子拖拽中的事件
    login.ondrag = function(){

        //测试用,也可以不用
        console.log('.....');
        // login.style.cursor = "crosshair";

    }

    //盒子拖拽结束事件
    login.ondragend = function(e) {

        //盒子最终的位置
        login.style.left = e.pageX - x + 256 + 'px';
        login.style.top = e.pageY - y - 140 + 'px';

        // login.style.cursor = "crosshair";
    }

</script>

但是有一个bug,鼠标的样式在拖拽过程中一直是禁止的样式。
未完待续!!!

猜你喜欢

转载自blog.csdn.net/weixin_42839080/article/details/81842669
今日推荐