JS-拖拽效果至 视窗 \ 边界

一. 拖拽至视窗

拖拽的效果 — 边界值
鼠标移动出页面,但是div要留在页面范围内
给定位数值,添加极限范围数值,
定位的最大值,最小值,都要有范围
最小值 : 上 左 都是 0

在这里插入图片描述

var oDiv = document.querySelector('div');

var oldTop = window.getComputedStyle(oDiv).top;
var oldLeft = window.getComputedStyle(oDiv).left;

视窗窗口的宽度,高度
var winWidth = document.documentElement.clientWidth;
var winHeight = document.documentElement.clientHeight;

当鼠标按下时,鼠标移动,添加事件
window.onmousedown = function(){
    window.onmousemove = function(e){
        // 根据 鼠标坐标,根据项目需求,计算定位的数值
        var x = e.clientX - oDiv.offsetWidth/2;
        var y = e.clientY - oDiv.offsetHeight/2;

        // 极限值判断
        // 最小值都是 0 0 
        if(x < 0){
            x = 0;
        }

        if(y < 0){
            y = 0;
        }

        // 最大值 可视窗口的宽度/高度 - ( 标签x轴方向 / y轴方向 最终占位 )

        if(x > winWidth - oDiv.offsetWidth){
            x = winWidth - oDiv.offsetWidth;
        }

        if(y > winHeight - oDiv.offsetHeight){
            y = winHeight - oDiv.offsetHeight;
        }
        console.log(x,y);
        // 将数值作为标签定位的坐标
        oDiv.style.left = x  + 'px' ;
        oDiv.style.top =  y + 'px' ;
    }
}

鼠标按键抬起时的移动不会让div跟随
window.onmouseup = function(){
    window.onmousemove = null;
}

总结思路

1,一定是 先按下事件,后移动事件 — 先砍头再移尸
2,鼠标抬起,给移动定义事件为null
也可以添加其他操作,例如,让标签回到原位
回到原始位置,需要在程序的起始位置,先记录原始的定位坐标
3,基本思路
(1),在定义函数之外,获取浏览器窗口的宽度,高度
不能带有滚动条
(2),获取鼠标的坐标,根据项目需求,来计算表现定位的数值
鼠标的坐标,要根据实际需求而定,目前使用的是相对可视窗口左上角的定位
项目需求不同,+ / - 的数值也不同
(3),设定极值
最小值为 0 0
最大值为 可视窗口宽度/高度 - 标签X轴/Y轴最终占位
(4),将最终的数据,作为标签定位的坐标
必须拼接px单位

二. 拖拽至边界值

在这里插入图片描述

<style>
    * {
        padding: 0;
        margin: 0;
    }

    body {
        height: 5000px;
    }

    .box {
        width: 800px;
        height: 800px;
        border: 10px solid #000;
        margin: 40px auto;
        position: relative;
        background: skyblue;
    }

    .inner {
        width: 100px;
        height: 100px;
        background: pink;
        position: absolute;
        top: 0;
        left: 0;
    }
</style>
</head>

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

<script>

    // 1,获取标签对象
    var oBox = document.querySelector('.box');
    var oInner = document.querySelector('.inner');

    // 2,获取相应的数据

    // 获取父级标签的---占位---不包括边框线
    var oBoxWidth = oBox.clientWidth;
    var oBoxHeight = oBox.clientHeight;


    // 获取子级标签的---占位---包括边框线
    var oInnerWidth = oInner.offsetWidth;
    var oInnerHeight = oInner.offsetHeight;

    // 给父级标签添加事件
    oInner.onmousedown = function () {

        document.onmousemove = function (e) {

            // 获取计算,设定子级标签定位的数值

            // page坐标 - 外边距 - 边框线 - 子级宽度的一半
            var x = e.pageX - oBox.offsetLeft - oBox.clientLeft - oInnerWidth / 2;
            var y = e.pageY - oBox.offsetTop - oBox.clientTop - oInnerHeight / 2;

            // 设定极限值

            // 最小值是0
            if (x < 0) {
                x = 0;
            }

            if (y < 0) {
                y = 0;
            }

            // 最大值 
            // 父级标签占位(没有border) - 移动标签占位(计算border)
            if (x > oBoxWidth - oInnerWidth) {
                x = oBoxWidth - oInnerWidth;
            }

            if (y > oBoxHeight - oInnerHeight) {
                y = oBoxHeight - oInnerHeight
            }

            // 将设定好的数值,作为子级标签的定位
            oInner.style.left = x + 'px';
            oInner.style.top = y + 'px';
        }
    }


    window.onmouseup = function () {
        document.onmousemove = null;
    }
// 思路步骤和问题
// 1, 事件,到底是绑定给 父级,子级,还是document,还是window
//    事件,取消,到底是通过谁取消
//    没有固定的写法,看你需要的效果
//    还是document和window效果相同,没有区别

//    鼠标按下
//    oInner.onmousedown   鼠标在粉色div上,按下鼠标,并且移动鼠标,才会有效果
//    oBox.onmousedown     鼠标在蓝色div上,按下鼠标,并且移动鼠标,才会有效果
//    window.onmousedown   鼠标在全屏上,按下鼠标,并且移动鼠标,都会有效果

//    鼠标移动
//    最好写成 document.onmousemove  /  window.onmousemove
//    鼠标可以快速移动,不怕移出粉色div

//    鼠标抬起
//    oInner.onmouseup     鼠标在粉色div上抬起,才会执行,标签不跟随移动
//    oBox.onmouseup       鼠标在蓝色div上抬起,才会执行,标签不跟随移动
//    window.onmouseup     鼠标在整个页面上抬起,都会执行,标签不跟随移动

// 2, 闪烁问题
//    原因: 相对于标签内容的左上角的定位
//          会因为鼠标经过不同的标签对象,获取不同的数据
//          而且JavaScript执行时,有时还会有bug产生
//          offsetX  offsetY  我们是不推荐使用的
//    解决: 使用 pageX 和  pageY 
//    定位: page距离 - 父级标签外边距 - 父级border - 移动标签占位/2(标签中心点和鼠标重合)
//   极值1: 左   上   都是 0
//   极值2: 右   下   父级标签占位(不算border) - 移动标签占位(计算border)
发布了103 篇原创文章 · 获赞 4 · 访问量 1989

猜你喜欢

转载自blog.csdn.net/DcTbnk/article/details/105281490