JavaScript - WebAPI - 案例 - 盒子拖拽

1.1-拖拽盒子 - 基本流程

在这里插入图片描述

思路分析

在这里插入图片描述

本小节知识点:鼠标拖拽

  • 复习鼠标事件:
    • onclick:鼠标点下去并且弹起来触发(单击一次)
    • ondblclick:鼠标连续点击两次(双击)
    • onmousedown:鼠标按下就触发
    • onmouseup: 鼠标弹起触发
    • onmouseover:鼠标移入
    • onmouseout:鼠标移出
    • onmousemove:鼠标移动
  • 鼠标拖拽:(1)先按下 (2)然后移动 (3)最后松开
<!DOCTYPE html>
<html lang="zh-CN">

<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>盒子拖拽 - 基本流程</title>
    <style>
        .box {
            position: absolute;
            left: 0;
            top: 0;


            width: 200px;
            height: 200px;
            background-color: red;
        }
    </style>
</head>

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

    <script>
        // 盒子拖拽: 三步骤
        const box = document.querySelector('.box')
        // 1. 鼠标按下: 记录鼠标相对位置
        box.onmousedown = function (e) {
            // console.log(e)
            // 减去原来位置的目的: 为了能够二次拖拽(如果只有一次性拖拽: 可以不用减去原有的偏移)
            let x = e.pageX - parseInt(getComputedStyle(box).left)
            let y = e.pageY - parseInt(getComputedStyle(box).top)
            console.log(x, y)
            // 上述代码不够优化: getComputedStyle(box)获取box的全部样式, 占用资源很多, 所以应该定义一个变量运行一次函数getComputedStyle()

            // 2. 鼠标移动: 一定在鼠标按下的事件内部, 移动盒子
            // 移动代表的是移动范围: 给移动范围对象增加移动事件
            document.onmousemove = function (e) {
                // 移动范围: 整个页面
                box.style.left = e.pageX - x + 'px'
                box.style.top = e.pageY - y + 'px'
            }

            // 3. 鼠标松开: 一定在鼠标按下的事件内容
            // 给谁加的按下事件,给谁加松开事件
            box.onmouseup = function () {
                // 释放document的移动事件
                document.onmousemove = null
            }
        }

    </script>
</body>

</html>

1.2-拖拽盒子02(元素有margin)

<!DOCTYPE html>
<html lang="zh-CN">

<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>盒子拖拽 - 带margin</title>
    <style>
        .box {
            position: absolute;
            left: 0;
            top: 0;


            width: 200px;
            height: 200px;
            background-color: red;

            margin-left: 50px;
        }
    </style>
</head>

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

    <script>
        // 盒子拖拽: 三步骤
        const box = document.querySelector('.box')
        // 1. 鼠标按下: 记录鼠标相对位置
        box.onmousedown = function (e) {
            // console.log(e)
            // 减去原来位置的目的: 为了能够二次拖拽(如果只有一次性拖拽: 可以不用减去原有的偏移)
            let x = e.pageX - parseInt(getComputedStyle(box).left)
            let y = e.pageY - parseInt(getComputedStyle(box).top)


            // 如果被拖拽的盒子有margin: 不要使用offset系列(自动带margin)
            // let x = e.pageX - box.offsetLeft
            // let y = e.pageY - box.offsetTop

            console.log(x, y)
            // 上述代码不够优化: getComputedStyle(box)获取box的全部样式, 占用资源很多, 所以应该定义一个变量运行一次函数getComputedStyle()

            // 2. 鼠标移动: 一定在鼠标按下的事件内部, 移动盒子
            // 移动代表的是移动范围: 给移动范围对象增加移动事件
            document.onmousemove = function (e) {
                // 移动范围: 整个页面
                box.style.left = e.pageX - x + 'px'
                box.style.top = e.pageY - y + 'px'
            }

            // 3. 鼠标松开: 一定在鼠标按下的事件内容
            // 给谁加的按下事件,给谁加松开事件
            box.onmouseup = function () {
                // 释放document的移动事件
                document.onmousemove = null
            }
        }

        // 但凡有盒子拖拽: 不用使用offset来获取偏移,用getComuptedStyle()获取真实的定位偏移

    </script>
</body>

</html>

1.3-案例:拖拽登录验证

在这里插入图片描述

<!DOCTYPE html>
<html lang="zh-CN">

<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>盒子拖拽 - 登陆验证</title>
    <style>
        .wrap {
            width: 360px;
            height: 180px;
            margin: 50px auto;
            border: 1px solid black;
            position: relative;
        }

        .wrap .icon {
            position: absolute;
            left: 0;
            top: 60px;
        }

        .wrap .progress {
            width: 100%;
            height: 40px;
            position: relative;
            top: -4px;
            background-color: pink;
        }

        .cube {
            position: absolute;
            width: 40px;
            height: 40px;
            background-color: red;
            cursor: pointer;
        }

        .bar {
            position: absolute;
            width: 0px;
            height: 40px;
            background-color: green;
        }
    </style>
</head>

<body>
    <div class="wrap">
        <img src="./images/drag01.png" alt="">
        <img class="icon" src="./images/drag02.png" alt="">
        <div class="progress">
            <div class="bar"></div>
            <div class="cube"></div>
        </div>
    </div>

    <script>
        // 需求: 拖拽登录验证
        // 细节1: 如果拖拽没有到达目标 或者 超出目标: 登录失败(刷新页面)
        // 细节2: 拖动多少代表成功呢? 

        // 拖拽三步走
        const wrap = document.querySelector('.wrap')
        const icon = document.querySelector('.wrap .icon')
        const bar = document.querySelector('.wrap .bar')
        const cube = document.querySelector('.wrap .cube')

        // 1. 鼠标按下: 几下鼠标当前位置
        cube.onmousedown = function (e) {
            let x = e.pageX

            // 2. 鼠标移动: 在整个框中拖动, 给框添加鼠标移动事件
            // 考虑安全: 不能小于0, 也不能大于框的宽度
            let distance = 0
            wrap.onmousemove = function (e) {
                distance = e.pageX - x
                // 安全
                if (distance < 0) distance = 0
                if (distance > wrap.offsetWidth - cube.offsetWidth) distance = wrap.offsetWidth - cube.offsetWidth

                icon.style.left = distance + 'px'
                bar.style.width = distance + 'px'
                cube.style.left = distance + 'px'
                console.log(distance)


            }
            // 3. 鼠标松开: 干掉移动事件, 判定拖动的距离是否满足验证条件
            cube.onmouseup = function () {
                wrap.onmousemove = null
                // 判定移动了多少

                if (distance >= 150 && distance <= 160) {
                    alert('验证成功,正在跳转')
                    location.assign('http://www.itcast.cn')
                } else {
                    alert('验证失败,请再次验证')
                    location.reload()
                }
            }
        }

        // 总结
        // 一次性拖拽: 不要算相对位置, 终点位置 - 起始位置 即可
        // mousemove里面的变量在mouseup中不能用: 要用,要提升变量

    </script>
</body>

</html>```

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Henry_ww

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值