使用JS制作一个鼠标可拖的DIV(1)

#Drag2 {

    /*border: 5px solid #C4E3FD;*/

    background: #ff0000;

    width: 50px;

    height: 50px;

    top: 50px;

    left: 50px;

    z-index: 3;

}
<div id="innerContainer">

    <div id="Drag" onmousedown="moveBind(this, event)">1</div>

    <div id="Drag2" onmousedown="moveBind(this, event)">2</div>

</div>


拖放状态:未开始




2.为了方便获得元素的位置和大小,先写一个方法来辅助(谷歌不能用了可恶orz,只能百度出这个方法并稍微做点修改)。



//获得元素的坐标与大小。

function findPosition(oElement) {

var x2 = 0;

var y2 = 0;

var width = oElement.clientWidth;

var height = oElement.clientHeight;

//alert(width + "=" + height);

if (typeof (oElement.offsetParent) != 'undefined') {

    for (var posX = 0, posY = 0; oElement; oElement = oElement.offsetParent) {

        posX += oElement.offsetLeft;

        posY += oElement.offsetTop;

    }

    x2 = posX + width;

    y2 = posY + height;

    return [posX, posY, x2, y2, width, height];



} else {

    x2 = oElement.x + width;

    y2 = oElement.y + height;

    return [oElement.x, oElement.y, x2, y2, width, height];

}

}




这里以数组的形式返回元素的 X 开始坐标和 Y 开始坐标,X 结束坐标和 Y 结束坐标,元素真实的宽与高(不算边框)



3.在鼠标按下事件里,先获得容器的位置数据:



//获得容器坐标。

var container = findPosition(document.getElementById(“innerContainer”));

var containerLeft = container[0];

var containerTop = container[1];

var containerWidth = container[4];

var containerHeight = container[5];




4.计算拖动 DIV 元素可移动的区域坐标:



/_计算出容器的范围坐标。_/



//开始 X 坐标。

var startX = containerLeft;

//开始 Y 坐标。

var startY = containerTop;

//结束 X 坐标。

var maxX = startX + containerWidth - width;

//结束 Y 坐标。

var maxY = startY + containerHeight - height;

开始 X 坐标 = 容器的左上角 X 坐标。

开始 Y 坐标 = 容器的左上角 Y 坐标。

结束 X 坐标 = 开始 X 坐标 + 容器的宽度 - 拖动 DIV 元素的宽度

结束 Y 坐标 = 开始 Y 坐标 + 容器的高度 - 拖动 DIV 元素的高度




5.当区域内存在多个可拖动的 DIV 元素时,要把当前鼠标点击的那个 DIV 设置成置顶显示。



//获得最大 Z 坐标。

function getMaxIndex() {

var index = 0;

var ds = document.getElementById('innerContainer').getElementsByTagName('div');

var length = document.getElementById('innerContainer').getElementsByTagName('div').length;



for (var loop = 0; loop < length; loop++) {

    if (ds[loop].style.zIndex > index) index = ds[loop].style.zIndex;

}



return parseInt(index);

}




该方法遍历容器内的所有 DIV 元素(即:可拖动元素),取得它们当中z-Index最大的值。



然后,设置点击元素的 z-Index 值:



//鼠标选中的元素设置成顶层。

obj.style.zIndex = getMaxIndex() + 1;

/*******************以上方法是在鼠标按下事件里 onmousedown ******************/

/*******************以下方法是在鼠标按下事件里 onmousemove ******************/




6.在移动事件里,修改元素位置的外层加上如下这条件。



//不可以超出指定的范围。

if (moveLeft >= startX && moveTop >= startY && moveLeft <= maxX && moveTop <= maxY) {

//当移动位置在范围内时,元素跟随鼠标移动。

obj.style.left = moveLeft + "px";

obj.style.top = moveTop + "px";

}




这条件表示:移动的位置在容器范围内时,元素才可以跟随鼠标移动。



但是,现在这样的做法,当鼠标快速拖出容器区域时,元素就会停止不动,但并没有移动到最边界,同时,鼠标在区域外并没有放开按键,移动鼠标时元素并不会跟着移动。



解决的思路是:



(1)当元素水平(X坐标)移动的位置没有达到或超出容器限制区域的 X 坐标区域时。



继续修改拖动元素的 X 坐标位置。



(2)当元素水平(X坐标)移动的位置超出容器限制区域的最大 X 坐标(即:容器右下角的 X 坐标)区域时(即:限制区域的右边),将元素的 X 坐标设置成最大 X 坐标值。



if (moveLeft >= startX && moveLeft <= maxX) {

                obj.style.left = moveLeft + "px";

            } else if (moveLeft > maxX) {

                obj.style.left = maxX + "px";

            }



(3)当元素水平(X坐标)移动的位置小于容器限制区域的开始 X 坐标(即:容器左上角的 X 坐标)区域时(即:限制区域的左边),将元素的 X 坐标设置成最小 X 坐标值。



if (moveLeft >= startX && moveLeft <= maxX) {

obj.style.left = moveLeft + "px";

} else if (moveLeft > maxX) {

obj.style.left = maxX + "px";

} else if (moveLeft < startX) {

obj.style.left = startX + "px";

}




(4)Y 坐标同以上(1)(2)(3):



    if (moveTop >= startY && moveTop <= maxY) {

        obj.style.top = moveTop + "px";

    } else if (moveTop > maxY) {

        obj.style.top = maxY + "px";

    } else if (moveTop < startY) {

        obj.style.top = startY + "px";

    }



完成了!这时,鼠标拖动到区域外面时,元素同样会跟随鼠标的位置在容器内移动。



二、以下是完整源码:  

JS部分:



//获得元素的坐标与大小。

function findPosition(oElement) {

    var x2 = 0;

    var y2 = 0;

    var width = oElement.clientWidth;

    var height = oElement.clientHeight;

    //alert(width + "=" + height);

    if (typeof (oElement.offsetParent) != 'undefined') {

        for (var posX = 0, posY = 0; oElement; oElement = oElement.offsetParent) {

            posX += oElement.offsetLeft;

            posY += oElement.offsetTop;

        }

        x2 = posX + width;

        y2 = posY + height;

        return [posX, posY, x2, y2, width, height];



    } else {

        x2 = oElement.x + width;

        y2 = oElement.y + height;

        return [oElement.x, oElement.y, x2, y2, width, height];

    }

}



function moveBind(obj, evnt) {

    //获得元素坐标。

    var left = obj.offsetLeft;

    var top = obj.offsetTop;

    var width = obj.offsetWidth;

    var height = obj.offsetHeight;



    //计算出鼠标的位置与元素位置的差值。

    var cleft = evnt.clientX - left;

    var ctop = evnt.clientY - top;



    //获得容器坐标。

    var container = findPosition(document.getElementById("innerContainer"));

    var containerLeft = container[0];

    var containerTop = container[1];

    var containerWidth = container[4];

    var containerHeight = container[5];



    /*计算出容器的范围坐标。*/



    //开始 X 坐标。

    var startX = containerLeft;

    //开始 Y 坐标。

    var startY = containerTop;

    //结束 X 坐标。

    var maxX = startX + containerWidth - width;

    //结束 Y 坐标。

    var maxY = startY + containerHeight - height;



    //鼠标选中的元素设置成顶层。

    obj.style.zIndex = getMaxIndex() + 1;



    //输出显示。

    //show("idShow", startX, startY);



    document.onmousemove = function (doc) {

        //计算出移动后的坐标。

        var moveLeft = doc.clientX - cleft;

        var moveTop = doc.clientY - ctop;



        //设置成绝对定位,让元素可以移动。

        obj.style.position = "absolute";



        //不可以超出指定的范围。

        if (moveLeft >= startX && moveTop >= startY && moveLeft <= maxX && moveTop <= maxY) {

            //当移动位置在范围内时,元素跟随鼠标移动。

            obj.style.left = moveLeft + "px";

            obj.style.top = moveTop + "px";

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。**

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-gy4SPObf-1715827662589)]

[外链图片转存中…(img-obCdvSfn-1715827662590)]

[外链图片转存中…(img-CNpGbAC3-1715827662590)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值