JavaScript拖放实现

拖放概念:点击某个对象,并按住鼠标按钮不放,将鼠标移动到另一个区域,然后释放鼠标按钮将对象放在这里。

基本思路:
创建一个绝对定位的元素,使其可以用鼠标移动。

本文通过实例代码讲解如何实现拖放功能。

HTML代码实现

在写js代码之前,我们先创建一个用于拖动的红色方块。

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <style type="text/css">
            .draggable{
                position:absolute;
                width:200px;
                height:200px;
                background:red;
            }
        </style>
    </head>
    <body>
        <div class = "draggable"></div>
        <div id="status"></div>
    </body>
</html>

JavaScript代码

注意:
本文会用到上篇文章中定义的EventUtil

var DragDrop = function(){
    var dragging = null;//拖动目标
    function handleEvent(event){
        //获取事件和目标
        event = EventUtil.getEvent();
        var target = EventUtil.getTarget(event);
        //事件类型选择
        switch(event.type){
            case "mousedown":
                if(target.className.indexOf("draggable")>-1){
                    dragging = target;
                }
                break;
            case "mousemove":
                if(dragging !== null){
                    //指定目标位置
                    dragging.style.left = event.clientX+"px";
                    dragging.style.top = event.clientY + "px";
                }
                break;
            case "mouseup":
                dragging = null;
                break;      
        }
    };
    //定义公共接口
    return{
        enable:function(){
            EventUtil.addHandler(document,"mousedown",handleEvent);
            EventUtil.addHandler(document,"mousemove",handleEvent);
            EventUtil.addHandler(document,"mouseup",handleEvent);
        },
        disable:function(){
            EventUtil.removeHandler(document,"mousedown",handleEvent);
            EventUtil.removeHandler(document,"mousemove",handleEvent);
            EventUtil.removeHandler(document,"mouseup",handleEvent);
        }
    }
}();
DragDrop.enable();

上述代码会让具有draggable类的元素都可以被拖动。

拖动功能修缮

当你实现代码,拖动红色方块的时候,会发现鼠标总是和红色方块的右上角在一起的,这个体验很糟糕,下面我们将展示修缮的代码,实现鼠标点击位置和红色方块的相对位置保持不变。
为了实现上述效果,我们需要在鼠标点击红色方块的时候,用两个值记录鼠标位置相对于红色方块的位置。
下图可以给出如何计算的答案:

这里写图片描述

JavaScript代码如下:

var DragDrop = function(){
    var dragging = null;//拖动目标
    var diffX = 0;//记录水平相对距离
    var diffY = 0;//记录竖直方向相对距离
    function handleEvent(event){
        //获取事件和目标
        event = EventUtil.getEvent();
        var target = EventUtil.getTarget(event);
        //事件类型选择
        switch(event.type){
            case "mousedown":
                if(target.className.indexOf("draggable")>-1){
                    dragging = target;
                    diffX = event.clientX - target.offsetLeft;
                    diffY = event.clientY - target.offsetTop;
                }
                break;
            case "mousemove":
                if(dragging !== null){
                    //指定目标位置
                    dragging.style.left = (event.clientX - diffX)+"px";
                    dragging.style.top = (event.clientY - diffY) + "px";
                }
                break;
            case "mouseup":
                dragging = null;
                break;      
        }
    };
    //定义公共接口
    return{
        enable:function(){
            EventUtil.addHandler(document,"mousedown",handleEvent);
            EventUtil.addHandler(document,"mousemove",handleEvent);
            EventUtil.addHandler(document,"mouseup",handleEvent);
        },
        disable:function(){
            EventUtil.removeHandler(document,"mousedown",handleEvent);
            EventUtil.removeHandler(document,"mousemove",handleEvent);
            EventUtil.removeHandler(document,"mouseup",handleEvent);
        }
    }

}();

DragDrop.enable();

注意:
如果看过我前面的JavaScript私有变量不难发现,我们上面定义的DragDrop对象是一个使用了模块模式的单例。

完善拖放功能—添加自定义事件

上面修缮的代码完全实现了拖放功能,下面我们将结合 JavaScript自定义事件,让应用的其他部分与拖动功能进行交互,用于指示拖动开始、正在拖动、拖动结束这几个事件。

最终代码:

var DragDrop = function(){

    var dragdrop = new EventTarget();//定义一个特定EventTarget类型的对象

    //私有变量和私有函数
    var dragging = null;//拖动目标
    var diffX = 0;//记录水平相对距离
    var diffY = 0;//记录竖直方向相对距离
    function handleEvent(event){//
        event = EventUtil.getEvent();
        var target = EventUtil.getTarget(event);
        //事件类型选择
        switch(event.type){
            case "mousedown":
                if(target.className.indexOf("draggable")>-1){
                    dragging = target;
                    diffX = event.clientX - target.offsetLeft;
                    diffY = event.clientY - target.offsetTop;
                    //触发自定义事件
                    dragdrop.fire({type:"dragstart",target:dragging,x:event.clientX,y:event.clientY})
                }
                break;
            case "mousemove":
                if(dragging !== null){
                    //指定目标位置
                    dragging.style.left = (event.clientX - diffX)+"px";
                    dragging.style.top = (event.clientY - diffY) + "px";
                    //触发自定义事件
                    dragdrop.fire({type:"drag",target:dragging,x:event.clientX,y:event.clientY})
                }
                break;
            case "mouseup":
                //触发自定义事件
                dragdrop.fire({type:"dragend",target:dragging,x:event.clientX,y:event.clientY})
                dragging = null;
                break;      
        }
    };


    //添加特权方法
    dragdrop.enable = function(){
        EventUtil.addHandler(document,"mousedown",handleEvent);
        EventUtil.addHandler(document,"mousemove",handleEvent);
        EventUtil.addHandler(document,"mouseup",handleEvent);
    };
    dragdrop.disable = function(){
        EventUtil.removeHandler(document,"mousedown",handleEvent);
        EventUtil.removeHandler(document,"mousemove",handleEvent);
        EventUtil.removeHandler(document,"mouseup",handleEvent);
    };
    return dragdrop;

}();
//定义是dragstart、drag、dragend三个事件,为每个事件添加事件处理程序
DragDrop.addHandler("dragstart",function(event){
    var status = document.getElementById("status");
    status.innerHTML = "Started draging"  +"'"+ event.target.id +"'";
});
DragDrop.addHandler("drag",function(event){
    var status = document.getElementById("status");
    status.innerHTML = "<br/>Dragged" +"'"+ event.target.id  +"'"+"to("+event.x+","+event.y+")";
});
DragDrop.addHandler("dragend",function(event){
    var status = document.getElementById("status");
    status.innerHTML = "<br/>Dropped" +"'" + event.target.id  +"'"+"to("+event.x+","+event.y+")";
});
DragDrop.enable();

提示:
看过增强的模块模式的应该都知道上述DragDrop对象是一个使用了增强的模块模式的单例。而这个单例就是EventTarget类型的实例。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值