关于js拖放功能的实现

这是具体的拖放代码的HTML,里面依赖两个组件:EventUtil.js是兼容浏览器添加方法的库,EventTarget.js是一个发布-订阅者模式的对象库。

EventUtil.js:

var EventUtil = {
    addHandler: function (element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent("on" + type, handler);
        } else {
            element["on" + type] = handler;
        }
    },
    removeHandler: function (element, type, handler) {
        if (element.removeEventListener) {
            element.removeEventListener(type, handler, false);
        } else if (element.detachEvent) {
            element.detachEvent("on" + type, handler);
        } else {
            element["on" + type] = null;
        }
    },
    getEvent: function (event) {
        return event ? event : window.event;
    },
    getTarget: function (event) {
        return event.target || event.srcElement;
    },
};

EventTarget.js:

function EventTarget() {
    this.handlers = {};
}
EventTarget.prototype = {
    constructor: EventTarget,
    addHandler: function (type, handler) {
        if (typeof this.handlers[type] == "undefined") {
            this.handlers[type] = [];
        }
        this.handlers[type].push(handler);
    },
    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++) {
                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;
                }
            }
            handlers.splice(i, 1);
        }
    }
};

以下是拖拽功能实现的全代码,功能性比较强大,支持在mousestart时候有回调,mousemove时候也有回调,mouseup时候trigger事件后执行之前的订阅回调。

<html>
<body>
    <div class="draggable" id="myDiv"></div>
    <div id="status"></div>
    <style>
        #myDiv {
            position: absolute;
            width: 200px;
            height: 200px;
            left: 0;
            top: 0;
            background-color: red;
        }
    </style>
</body>
<script src="EventUtil.js"></script>
<script src="EventTarget.js"></script>
<script>
    //event:传入的是事件类型
    // EventUtil.addHandler(document, "mousemove", function (event) {
    //     var myDiv = document.getElementById("myDiv");
    //     myDiv.style.left = event.clientX + "px";
    //     myDiv.style.top = event.clientY + "px";
    // });
    var DragDrop = function () {
        var dragdrop = new EventTarget(),
            dragging = null,
            diffX = 0,
            diffY = 0;

        function handleEvent(event) {
            event = EventUtil.getEvent(event);
            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
    }()
    DragDrop.addHandler("dragstart",function(event){
        var status = document.getElementById('status');
        status.innerHTML = 'Started dragging '+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/>Drapped ${event.target.id} at ${event.x},${event.y}`;
    })
    DragDrop.enable()
</script>

</html>

【完】

无论多么难懂的书,读的次数多了,自然就懂了。

 

原文地址:https://www.cnblogs.com/tangjiao/p/10020138.html