【前端基础】offset系列属性练习--拖曳模态框(JS)

7 阅读3分钟

摘要

主要利用offset系列属性,以及三个鼠标事件(mousedown,mousemove,mouseup)实现拖曳模态框改变模态框位置的效果。

一、实现思路

1.首先需要一个模态框(这里只是举例,尽可能简洁)

<div class = "box"></div>

2.为模态框设置样式

<style>
    .box{
        position:fixed;
        left:100px;
        top:100px;
        width:500px;
        height:200px;
        background-color:blue;
    }
</style>

3.为模态框绑定事件
核心思路:
a.在鼠标按下(mousedown)时,记录鼠标相对于盒子(.box)的坐标;
b.在鼠标移动时,利用e.pageX和e.pageY属性实时获取鼠标距离页面上边和左边的距离;再用e.pageX/Y减去鼠标相对于盒子的坐标就能得到移动后盒子的left/top值;最后将获取的值赋给.box的left和top属性;
c.在鼠标弹起(mouseup)时,解绑鼠标移动事件(!由于解绑函数的语法限制,所以最好直接给鼠标移动函数起个函数名)。

<script>
    var box = document.querySelector(".box");
    box.addEventListener("mousedown",function(e){
        var x = e.pageX - this.offsetLeft;
        var y = e.pageY - this.offsetTop;
        document.addEventListener("mousemove",move);
        function move(e){
            this.style.left = e.pageX - x + "px";
            this.style.top = e.pageY - y + "px";
        }
        document.addEventListener("mouseup",function(){
            document.removeEventListener("mousemove",move);
        }
    })
</script>

二、易错点

1.注意在为box的left/top属性赋值时,一定要加单位(px)
2.鼠标移动监听事件要放在鼠标按下的事件里面,注意逻辑关系
3.!注意使用offset属性时,其父级元素要有定位,否则默认父元素为body(这里父元素就是body,但尽量养成良好习惯,不能经常性省略)

三、完整案例代码

实现的功能

1.点击文字“点击打开模态框”,模态框会弹出;点击右上角的“×”模态框会关闭
2.拖曳模态框只有在框的上1/4才会起作用

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>拖曳模态框</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        input {
            width: 200px;
            height: 25px;
            outline: none;
            border: 1px solid #999;
            border-radius: 5px;
        }

        .header {
            margin: 0 auto;
            width: 150px;
            height: 50px;
            text-align: center;
            font-size: 20px;
            font-weight: 700;
        }

        .box {
            z-index: 99;
            display: none;
            position: fixed;
            left: 50%;
            top: 50%;
            width: 500px;
            height: 250px;
            border: 1px solid #666;
            box-shadow: 5px 5px 5px #999;
            border-radius: 10px;
            background-color: #fff;
            transform: translate(-50%, -50%);
        }

        .login-title {
            position: relative;
            height: 50px;
            line-height: 50px;
            font-style: 16px;
            text-align: center;
        }

        .login-title span {
            position: absolute;
            right: -20px;
            top: -20px;
            width: 40px;
            height: 40px;
            line-height: 40px;
            font-size: 18px;
            border-radius: 20px;
            border: 1px solid #666;
            background-color: #fff;
        }

        .input-content {
            height: 140px;
        }

        .input {
            height: 70px;
            padding-left: 130px;
        }

        .input:first-child {
            padding-top: 25px;
            padding-left: 115px;
        }

        .login {
            margin-left: 155px;
            width: 210px;
            height: 35px;
            text-align: center;
            line-height: 35px;
            color: #fff;
            border-radius: 5px;
            background-color: blueviolet;
        }
    </style>
</head>

<body>
    <div class="header">点击弹出模态框</div>
    <div class="box" id="box">
        <div class="login-title">
            会员登录
            <span>×</span>
        </div>
        <div class="input-content">
            <div class="input">
                <label for="">用户名</label>
                <input type="text">
            </div>
            <div class="input">
                <label for="">密码</label>
                <input type="password">
            </div>
        </div>
        <div class="login">登录</div>
    </div>
    <script>
        var body = document.body;
        var box = document.querySelector(".box");
        var header = document.querySelector(".header");
        var span = document.querySelector("span");
        var title = document.querySelector(".login-title");
        header.addEventListener("click", function () {
            box.style.display = "block";
            body.style.backgroundColor = 'rgba(0,0,0,.3)';
        })
        span.addEventListener("click", function () {
            box.style.display = "none";
            body.style.backgroundColor = '';
        })
        title.addEventListener("mousedown", function (e) {
            var x = e.pageX - box.offsetLeft;
            var y = e.pageY - box.offsetTop;
            document.addEventListener("mousemove", move);
            function move(e) {
                box.style.left = e.pageX - x + 'px';
                box.style.top = e.pageY - y + 'px';
            }
            document.addEventListener("mouseup", function () {
                document.removeEventListener('mousemove', move);
            })
        })

    </script>
</body>

</html>

新手小白,大佬嘴下留情,希望能给我些建议!