javascript事件(三)(实现拖拽)

一.拖拽的原理:选择元素时(鼠标按下),保存鼠标的位置和元素位置的差值(以保证鼠标拖住元素移动时相对于元素的位置固定);移动元素时(鼠标移动),不停地给元素位置赋值(当前鼠标位置减去保存的差值);释放元素时(鼠标抬起),取消移动事件。

二.可能会遇到的问题
1.若移动速度太快脱离元素时事件就不会执行了;
2.为了避免冒泡,onmousemove事件放在document上就可以了;
3.为了避免当鼠标在其他元素上抬起时元素不会停止运动,故将onmouseup事件也放在document上;
4.鼠标按下时,如果有文字被选中,拖拽会变成复制(浏览器默认行为),这时就会出现冲突,避免该冲突的做法:
A.标准浏览器下:
需要在onmousedown阻止默认行为来防止(非标准浏览器下无效)。
B.IE下:
IE浏览器里有个全局捕获(和事件流里面的捕获不同)。全局捕获的意思是当有其他元素执行一个事件时劫持该事件,在释放元素时需要把全局捕获也释放。

//全局捕获劫持事件
if(元素.setCapture){
    元素.setCapture();
}

...
//释放元素时释放全局捕获
if(元素.releaseCapture){
元素.releaseCapture();
}

这样也可以达到和阻止默认事件一样的效果。

三.封装拖拽(限制范围的拖拽)

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
#box{width:100px; height:100px; background-color:red; position:absolute; left:100px; top:100px; z-index:5;}
#box1{width:500px; height:500px; background-color:green; position:absolute; left:100px; top:100px; z-index:3;}
</style>
</head>
<body style="height:2000px;">
<div id="box"></div>
<div id="box1"></div>
<script>
var oDiv = document.getElementById('box');
var oDiv1 = document.getElementById('box1');
downMove(oDiv,oDiv1);


function downMove(ele,ele2){
    ele.onmousedown = function(ev){
        var ev = ev || event;
        if(ele.setCapture){ele.setCapture();}
        var scrollTop =  document.body.scrollTop || document.documentElement.scrollTop;
        var scrollLeft =  document.body.scrollLeft || document.documentElement.scrollLeft;
        var disX = ev.clientX - ele.offsetLeft + scrollLeft;
        var disY = ev.clientY - ele.offsetTop + scrollTop;
        document.onmousemove = function(ev){
            var ev = ev || event;
            var scrollTop =  document.body.scrollTop || document.documentElement.scrollTop;
            var scrollLeft =  document.body.scrollLeft || document.documentElement.scrollLeft;
            var oLeft = ev.clientX - disX + scrollLeft;
            if(oLeft<ele2.offsetLeft){
                oLeft = ele2.offsetLeft;
            }
            if(oLeft>ele2.offsetLeft+ele2.offsetWidth-ele.offsetWidth){
                oLeft = ele2.offsetLeft+ele2.offsetWidth-ele.offsetWidth;
            }
            var oTop = ev.clientY - disY + scrollTop;
            if(oTop<ele2.offsetTop){
                oTop = ele2.offsetTop;
            }
            if(oTop>ele2.offsetTop+ele2.offsetHeight-ele.offsetHeight){
                oTop = ele2.offsetTop+ele2.offsetHeight-ele.offsetHeight;
            }
            ele.style.left = oLeft +'px';
            ele.style.top = oTop + 'px';
        }
        document.onmouseup = function(){
            if(ele.releaseCapture){ele.releaseCapture();}
            document.onmousemove = document.onmouseup = null;
        }
        return false;
    }
}
</script>
</body>
</html>

这里写图片描述

练习1:在上面封装的基础上,做一个磁性吸附效果(当元素距离边界小于50像素时,像磁铁一样一下吸附过去)

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
#box{width:100px; height:100px; background-color:red; position:absolute; left:100px; top:100px; z-index:5;}
#box1{width:500px; height:500px; background-color:green; position:absolute; left:100px; top:100px; z-index:3;}
</style>
</head>

<body>
    <div id="box"></div>
    <div id="box1"></div>
    <script>
        var oDiv=document.getElementById("box");
        var oDiv1=document.getElementById("box1");
        downMove(oDiv,oDiv1);
        function downMove(ele,ele2){
            ele.onmousedown = function(ev){
                var ev = ev || event;
                if(ele.setCapture){ele.setCapture();}
                var scrollTop =  document.body.scrollTop || document.documentElement.scrollTop;
                var scrollLeft =  document.body.scrollLeft || document.documentElement.scrollLeft;
                var disX = ev.clientX - ele.offsetLeft + scrollLeft;
                var disY = ev.clientY - ele.offsetTop + scrollTop;
                document.onmousemove = function(ev){
                    var ev = ev || event;
                    var scrollTop =  document.body.scrollTop || document.documentElement.scrollTop;
                    var scrollLeft =  document.body.scrollLeft || document.documentElement.scrollLeft;
                    var oLeft = ev.clientX - disX + scrollLeft;
                    if(oLeft<ele2.offsetLeft+50){
                        oLeft = ele2.offsetLeft;
                    }
                    if(oLeft>ele2.offsetLeft+ele2.offsetWidth-ele.offsetWidth-50){
                        oLeft = ele2.offsetLeft+ele2.offsetWidth-ele.offsetWidth;
                    }
                    var oTop = ev.clientY - disY + scrollTop;
                    if(oTop<ele2.offsetTop+50){
                        oTop = ele2.offsetTop;
                    }
                    if(oTop>ele2.offsetTop+ele2.offsetHeight-ele.offsetHeight-50){
                        oTop = ele2.offsetTop+ele2.offsetHeight-ele.offsetHeight;
                    }
                    ele.style.left = oLeft +'px';
                    ele.style.top = oTop + 'px';
                }
                document.onmouseup = function(){
                    if(ele.releaseCapture){ele.releaseCapture();}
                    document.onmousemove = document.onmouseup = null;
                }
                return false;
            }
        }
    </script>
</body>
</html>

四.拖拽的延伸
1.碰撞检测:就是检查是否有重合(思路:九宫格方式判断)
练习2:做一个方块和图片碰撞时,图片切换成另一张图片,离开时变回。

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
#box{width:100px; height:100px; background-color:red; position:absolute; left:100px; top:100px; z-index:5;}
#box1{width:500px; height:500px; background-color:green; position:absolute; left:100px; top:100px; z-index:3;}
</style>
</head>

<body style="height:2000px;">
    <div id="box"></div>
    <div id="box1"></div>
    <script>
    var oDiv = document.getElementById('box');
    var oDiv1 = document.getElementById('box1');
    downMove(oDiv,document,oDiv1);
    function downMove(ele,ele2,ele3){
        ele.onmousedown = function(ev){
            var ev = ev || event;
            if(ele.setCapture){ele.setCapture();}
            var scrollTop =  document.body.scrollTop || document.documentElement.scrollTop;
            var scrollLeft =  document.body.scrollLeft || document.documentElement.scrollLeft;
            var disX = ev.clientX - ele.offsetLeft + scrollLeft;
            var disY = ev.clientY - ele.offsetTop + scrollTop;
            document.onmousemove = function(ev){
                var ev = ev || event;
                var scrollTop =  document.body.scrollTop || document.documentElement.scrollTop;
                var scrollLeft =  document.body.scrollLeft || document.documentElement.scrollLeft;
                if(ele2==document){
                    ele2.offsetLeft=scrollLeft;
                    ele2.offsetTop=scrollTop;
                    ele2.offsetWidth=document.documentElement.clientWidth;
                    ele2.offsetHeight=document.documentElement.clientHeight;
                }
                var oLeft = ev.clientX - disX + scrollLeft;
                if(oLeft<ele2.offsetLeft){
                    oLeft = ele2.offsetLeft;
                }
                if(oLeft>ele2.offsetLeft+ele2.offsetWidth-ele.offsetWidth){
                    oLeft = ele2.offsetLeft+ele2.offsetWidth-ele.offsetWidth;
                }
                var oTop = ev.clientY - disY + scrollTop;
                if(oTop<ele2.offsetTop){
                    oTop = ele2.offsetTop;
                }
                if(oTop>ele2.offsetTop+ele2.offsetHeight-ele.offsetHeight){
                    oTop = ele2.offsetTop+ele2.offsetHeight-ele.offsetHeight;
                }
                if(oLeft+ele.offsetWidth>ele3.offsetLeft&&oTop+ele.offsetHeight>ele3.offsetTop&&ele3.offsetLeft+ele3.offsetWidth>oLeft&&ele3.offsetTop+ele3.offsetHeight>oTop){
                //碰撞时背景色变为黄色
                    ele3.style.backgroundColor='yellow';
                }else{
                //离开时背景色变为绿色
                    ele3.style.backgroundColor='green';
                }
                ele.style.left = oLeft +'px';
                ele.style.top = oTop + 'px';
            }
            document.onmouseup = function(){
                if(ele.releaseCapture){ele.releaseCapture();}
                document.onmousemove = document.onmouseup = null;
            }
            return false;
        }
    }
    </script>
</body>
</html>

这里写图片描述

这里写图片描述

2.拖拽改变元素大小
练习3:先找到鼠标按下时,它在元素的什么位置(判断要改变哪个方向),每个方向–上下左右分别为:改变height和top值;改变height;改变width和left值;改变width

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
#box{width:100px; height:100px; background-color:red; position:absolute; left:100px; top:100px;}
</style>
</head>

<body>
<div id="box"></div>
<script>
var oDiv = document.getElementById('box');
downMove(oDiv,document);
var oLeft=0;
var oTop=0;
var i=0;
function downMove(ele,ele2){
    ele.onmousedown = function(ev){
        var ev = ev || event;
        if(ele.setCapture){ele.setCapture();}
        var scrollTop =  document.body.scrollTop || document.documentElement.scrollTop;
        var scrollLeft =  document.body.scrollLeft || document.documentElement.scrollLeft;
        var disX = ev.clientX - ele.offsetLeft + scrollLeft;
        var disY = ev.clientY - ele.offsetTop + scrollTop;
        document.onmousemove = function(ev){
            var ev = ev || event;
            var scrollTop =  document.body.scrollTop || document.documentElement.scrollTop;
            var scrollLeft =  document.body.scrollLeft || document.documentElement.scrollLeft;
            if(ele2==document){
                ele2.offsetLeft=scrollLeft;
                ele2.offsetTop=scrollTop;
                ele2.offsetWidth=document.documentElement.clientWidth;
                ele2.offsetHeight=document.documentElement.clientHeight;
            }
            i++;
            var oLeft1=oLeft;
            oLeft = ev.clientX - disX + scrollLeft;
            if(oLeft<ele2.offsetLeft){
                oLeft = ele2.offsetLeft;
            }
            if(oLeft>ele2.offsetLeft+ele2.offsetWidth-ele.offsetWidth){
                oLeft = ele2.offsetLeft+ele2.offsetWidth-ele.offsetWidth;
            }

            var oTop1=oTop;
            oTop = ev.clientY - disY + scrollTop;
            if(oTop<ele2.offsetTop){
                oTop = ele2.offsetTop;
            }
            if(oTop>ele2.offsetTop+ele2.offsetHeight-ele.offsetHeight){
                oTop = ele2.offsetTop+ele2.offsetHeight-ele.offsetHeight;
            }
            ele.style.left = oLeft +'px';
            ele.style.top = oTop + 'px';
            if((disX>0&&disX<20)&&(disY>20&&disY<ele.offsetHeight-20)){
                if(oLeft1<oLeft){
                    ele.style.width=ele.offsetWidth+3+'px';
                }else if(oLeft1>oLeft){
                    ele.style.width=ele.offsetWidth-3+'px';
                }
            }
            if(((disX>ele.offsetWidth-20*i)&&(disX<ele.offsetWidth))&&(disY>20&&disY<ele.offsetHeight-20)){
                if(oLeft1<oLeft){
                    ele.style.width=ele.offsetWidth+3+'px';
                }else if(oLeft1>oLeft){
                    ele.style.width=ele.offsetWidth-3+'px';
                }
            }
            if((disY>0&&disY<20)&&(disX>20&&disX<ele.offsetWidth-20)){
                if(oTop1<oTop){
                    ele.style.height=ele.offsetHeight+3+'px';
                }else if(oTop1>oTop){
                    ele.style.height=ele.offsetHeight-3+'px';
                }
            }
            if((disY>ele.offsetHeight-20*i&&disY<ele.offsetHeight)&&(disX>20&&disX<ele.offsetWidth-20)){
                if(oTop1<oTop){
                    ele.style.height=ele.offsetHeight+3+'px';
                }else if(oTop1>oTop){
                    ele.style.height=ele.offsetHeight-3+'px';
                }
            }
        }
        document.onmouseup = function(){
            if(ele.releaseCapture){ele.releaseCapture();}
            document.onmousemove = document.onmouseup = null;
        }
        return false;
    }
}
</script>
</body>
</html>

3.模拟滚动条:定义一个元素在另一个元素里拖拽,只需要一个方向移动。原理:内部元素的top和两个元素高度差的比例,等于当前要控制的滚动条scrollTop和整个页面高度的比例

练习4:做一个限制范围的模拟滚动条

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
#box{width:20px; height:50px; background-color:red; position:absolute; left:100px; top:100px; z-index:5;}
#box1{width:20px; height:500px; background-color:green; position:absolute; left:100px; top:100px; z-index:3;}
</style>
</head>
<body style="height:2000px;">
<div id="box"></div>
<div id="box1"></div>
<script>
var oDiv = document.getElementById('box');
var oDiv1 = document.getElementById('box1');
downMove(oDiv,oDiv1,0);


function downMove(ele,ele2,adsorb){
    ele.onmousedown = function(ev){
        var ev = ev || event;
        if(ele.setCapture){ele.setCapture();}
        var scrollTop =  document.body.scrollTop || document.documentElement.scrollTop;
        var disY = ev.clientY - ele.offsetTop + scrollTop;
        document.onmousemove = function(ev){
            var ev = ev || event;
            var scrollTop =  document.body.scrollTop || document.documentElement.scrollTop;
            var  eleTop  = eleHeight = null;
            if(ele2 == 'allWindow'){
                eleTop = scrollTop;
                eleHeight = document.documentElement.clientHeight;
            }else{
                eleTop = ele2.offsetTop;
                eleHeight = ele2.offsetHeight;
            }
            var oTop = ev.clientY - disY + scrollTop;
            if(oTop<eleTop +adsorb){
                oTop = eleTop;
            }
            if(oTop>eleTop+eleHeight-ele.offsetHeight -adsorb){
                oTop = eleTop+eleHeight-ele.offsetHeight;
            }
            ele.style.top = oTop + 'px';
        }
        document.onmouseup = function(){
            if(ele.releaseCapture){ele.releaseCapture();}
            document.onmousemove = document.onmouseup = null;
        }
        return false;
    }
}

</script>
</body>
</html>

这里写图片描述

练习5:做一个滚动条下拉一个元素高度跟着改变,直到元素高度等滚动条高度

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
#box{width:20px; height:60px; background-color:red; position:absolute; left:500px; top:100px; z-index:5;}
#box1{width:20px; height:1000px; background-color:green; position:absolute; left:500px; top:100px; z-index:3;}
#box2{width:100px;background-color:pink;position:absolute;top:100px; left:540px; }
</style>
</head>

<body>
<body style="height:2000px;">
<div id="box"></div>
<div id="box1"></div>
<div id="box2"></div>
<script>
var oDiv = document.getElementById('box');
var oDiv1 = document.getElementById('box1');
var oDiv2 = document.getElementById('box2');
downMove(oDiv,oDiv1,oDiv2);


function downMove(ele,ele2,ele3){
    ele.onmousedown = function(ev){
        var ev = ev || event;
        if(ele.setCapture){ele.setCapture();}
        var scrollTop =  document.body.scrollTop || document.documentElement.scrollTop;
        var scrollLeft =  document.body.scrollLeft || document.documentElement.scrollLeft;
        var disX = ev.clientX - ele.offsetLeft + scrollLeft;
        var disY = ev.clientY - ele.offsetTop + scrollTop;
        document.onmousemove = function(ev){
            var ev = ev || event;
            var scrollTop =  document.body.scrollTop || document.documentElement.scrollTop;
            var scrollLeft =  document.body.scrollLeft || document.documentElement.scrollLeft;
            var oTop = ev.clientY - disY + scrollTop;
            if(oTop<ele2.offsetTop){
                oTop = ele2.offsetTop;
            }
            if(oTop>ele2.offsetTop+ele2.offsetHeight-ele.offsetHeight){
                oTop = ele2.offsetTop+ele2.offsetHeight-ele.offsetHeight;
            }
            ele3.style.height=(ele.offsetTop-ele2.offsetTop)*ele2.offsetHeight/(ele2.offsetHeight-ele.offsetHeight) + 'px';
            ele.style.top = oTop + 'px';
        }
        document.onmouseup = function(){
            if(ele.releaseCapture){ele.releaseCapture();}
            document.onmousemove = document.onmouseup = null;
        }
        return false;
    }
}
</script>
</body>
</html>

这里写图片描述

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值