JavaScript拖放功能实现

本文介绍了一种实现自定义事件与拖放功能的方法,包括事件注册、删除及跨浏览器兼容性的处理。通过封装EventUtil和DragDrop类,实现了元素的拖动,并通过自定义事件监听器实时更新状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

<div id="status" class="draggable" style="position: absolute; background-color: red; width: 200px; height: 200px"></div>

    <script>
        //封装一些有关事件注册 删除的方法
        var EventUtil = {
            //此函数用来添加事件
            addHandler:function(element,type,handler){
                //是否存在DOM2级方法
                if(element.addEventListener){
                    element.addEventListener(type, handler, false);
                }
                //IE方法
                else if (element.attachEvent){
                    element.attachEvent("on" + type, handler);
                }
                //DOM0级方法
                else{
                    element["on" + type] = handler;
                }
            },
            //获取事件对象
            getEvent: function(event){
                return event?event : window.event;
            },
            //获取事件目标
            getTarget: function(event){
                return event.target || event.srcElement;
            },
            //阻止事件默认行为
            preventDefault: function(event){
                if(event.preventDefault){
                    event.preventDefault();
                }
                else{
                    event.returnValue = false;
                }
            },
            //阻止事件流
            stopPropagation: function(event){
                if(event.stopPropagation){
                    event.stopPropagation();
                }
                else{
                    event.cancelBubble = true;
                }
            },

            //删除事件
            removeHandler: function(element, type, handler){
                //是否存在DOM2级方法
                if(element.removeEventListener){
                    element.removeEventListener(type, handler, false);
                }
                //IE方法
                else if(element.detachEvent){
                    element.detachEvent("on" + type, handler);
                }
                //DOM0级方法
                else{
                    element["on" + type] = null;
                }
            }
        };
        // EventTarget为自定义事件函数
        function EventTarget(){
            //EventTart类型有一个单独的属性handlers,用于存储事件处理程序
            this.handlers = {};
        }
        EventTarget.prototype = {
            //重新指向EventTarget函数
            constructor: EventTarget,
            //type:事件类型 handler: 用于处理该事件的函数
            addHandler:function(type,handler){
                //判断handlers对象中是否存在属性名为type的属性
                if(typeof this.handlers[type] == "undefined"){
                    //如果不存在就将属性名为type属性的属性值设置为一个新数组,用于存放type类型的事件处理程序
                    this.handlers[type] = [];
                }
                //将handler事件处理函数添加到数组末尾
                this.handlers[type].push(handler);
            },

            //fire()函数要接受一个至少包含type属性的对象作为参数
            fire: function(event){
                if(!event.target){
                    event.target = this;
                }
                //判断要触发的消息是否存在
                if(this.handlers[event.type] instanceof Array){
                    //获取对应类型的事件处理程序
                    var handlers = this.handlers[event.type];
                    for(var i=0,len = handlers.length; i<len; i++){
                        //调用每个函数,并给出event对象
                        handlers[i](event);
                    }
                }
            },

            removeHandler: function(type, handler){
                //防止删除的消息不存在的情况
                if(this.handlers[type] instanceof Array){
                    var handlers = this.handlers[type];
                    for(var i=0,len = handlers.length;i<len;i++){
                        if(handlers[i] === handler){
                            break;
                        }
                    }
                    //将i位置的事件处理程序删除
                    handlers.splice(i,1);
                }
            }
        };
        // DragDrop里面封装拖放的所有基本功能
        var DragDrop = function(){
            //用来存放被拖动的元素
            var dragging = null;
            var dragdrop = new EventTarget(),
                diffx=0,diffy=0;
            //handleEvent处理拖放功能的三个鼠标事件
            function handleEvent(event){
                //获取event对象与事件目标的引用
                event = EventUtil.getEvent(event);
                var target = EventUtil.getTarget(event);
                //判断事件类型
                switch(event.type){
                    case "mousedown":
                    //检查target事件目标的class是否包含“draggable”类
                        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":
                    // draggable不为空,则它就是拖动对象
                        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;
        };


        //调用
        var DragDrop = DragDrop();
        DragDrop.enable();

        //注册自定义事件dragstart
        DragDrop.addHandler("dragstart",function(event){
            var status = document.getElementById("status");
            status.innerHTML = "Started dragging" + event.target.id;
        });
        //注册自定义事件drag
        DragDrop.addHandler("drag",function(event){
            var status = document.getElementById("status");
            status.innerHTML += "<br/>Dragged" + event.target.id + " to ("+ event.x + "," + event.y + ")";
        });
        //注册自定义事件dragend
        DragDrop.addHandler("dragend",function(event){
            var status = document.getElementById("status");
            status.innerHTML += "<br/>Dropped" + event.target.id + " at (" +event.x + "," + event.y + ")";
        });
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

1planet

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

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

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

打赏作者

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

抵扣说明:

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

余额充值