search

Home  >  Q&A  >  body text

javascript - 为什么这个用JS写的拖拽元素的方法应用到多个元素上会同时奏效?

我封装了这个函数,用于实现元素的拖拽,如下:

;(function(){
    var funcBody = {
        "addEvent" : addEvent,
        "getEventObj" : getEventObj,
        "getTarget" : getTarget,
        "preventDefault" : preventDefault,
        "removeEvent" : removeEvent,
        "getMouseDistance" : getMouseDistance,
        "mouseMoveFunc" : mouseMoveFunc,
        "moveElement" : moveElement,
        "getChangeValue" : getChangeValue,
        "setElementLT": setElementLT,
        "funcX" : funcX,
        "funcY" : funcY,
    }
//绑定事件处理程序
function addEvent(element,type,func){
    if(element.addEventListener){
        element.addEventListener(type,func,false);
    }else if(element.attachEvent){
        element.attachEvent("on"+type,func);
    }else{
        element["on"+type] = func;
    }
}

//获取event对象
function getEventObj(event){
    return event?event:window.event;
}

//event的target事件目标
function getTarget(event){
    return event.target||event.srcElement;
}

//取消元素默认行为
function preventDefault(event){
    if(event.preventDefault){
        event.preventDefault();
    }else{
        event.returnValue = false;
    }
}

//移除事件处理程序
function removeEvent(element,type,func){
    if(element.removeEventListener){
        element.removeEventListener(type,func,false);
    }else if(element.detachEvent){
        element.detachEvent("on"+type,func);
    }else{
        element["on"+type] = false;
    }
}

    //鼠标拖拽
    function moveElement(element,referenceElement,direction,minDirection,maxDirection,func){
        funcBody.addEvent(element,"mousedown",getMouseDistance);
        funcBody.addEvent(document,"mouseup",mouseUpFunc);
        var returnValue = null;
        switch(direction){
            case "x": funcBody.addEvent(referenceElement,"mousemove",mouseMoveFunc(element,"x",minDirection,maxDirection,func));
                break;
            case "y": funcBody.addEvent(referenceElement,"mousemove",mouseMoveFunc(element,"y",minDirection,maxDirection,func));
                break;
            case "xy": funcBody.addEvent(referenceElement,"mousemove",mouseMoveFunc(element,"xy",minDirection,maxDirection,func));
                break;
        }
    }

    var canMove = false;  //设置标记用于判断是否点击了拖拽元素
    var mouseOffsetX = 0,
        mouseOffsetY = 0;

//鼠标点击元素获取鼠标距元素左侧和顶部的距离
function getMouseDistance(){
    event = funcBody.getEventObj(event);
    target = funcBody.getTarget(event);
    mouseOffsetX = event.pageX - target.offsetLeft;
    mouseOffsetY = event.pageY - target.offsetTop;
    canMove = true;
}

function getChangeValue(func){
    func();
}

//鼠标在元素上移动时执行某函数
function mouseMoveFunc(element,direction,minDirection,maxDirection,func){
    return function(){
        if(canMove === true){
            event = arguments[0]||window.event;
            var mouseX = 0;
            var mouseY = 0;
            mouseX = event.pageX - mouseOffsetX;
            mouseY = event.pageY - mouseOffsetY;
            funcBody.setElementLT(element,mouseX,mouseY,minDirection,maxDirection,direction);
            funcBody.getChangeValue(func);
        }
    }
}

//鼠标按键抬起时将canMove设为false
function mouseUpFunc(){
    canMove = false;
}

//设置元素的left和top值
function setElementLT(element,x,y,min,max,deriction){
    switch(deriction){
        case "x":funcX(element,x,min,max);break;
        case "y":funcY(element,y,min,max);break;
        case "xy":funcX(element,x,min,max);
                  funcY(element,y,min,max);
                  break;
    }
}
function funcX(element,value,min,max){
    if(value<min){
        element.style.left = min + "px";
    }else if(value>max){
        element.style.left = max + "px";
    }else{
        element.style.left = value + "px";
    }
}
function funcY(element,value,min,max){
    if(value<min){
        element.style.top = min + "px";
    }else if(value>max){
        element.style.top = max + "px";
    }else{
        element.style.top = value + "px";
    }
}
window.funcBody = funcBody;
})(window);

最终用来实现元素拖拽的方法就是这个moveElement()方法,比如要在document的水平方向上拖拽p1元素,且拖拽的水平坐标区间为(0,500),在拖拽过程中执行func方法,就如下写:

funcBody.moveElement(p1,document,"x",0,500,func);

但是问题是,如果有两个或者多个元素同时要实现拖拽效果的话,拖拽一个元素另外的元素也会随这个元素一起动,麻烦大神们帮我看下是什么原因。

PHPzPHPz2804 days ago691

reply all(2)I'll reply

  • ringa_lee

    ringa_lee2017-04-11 09:57:10

    canMove是全局变量,mousemove又是加到document了,当然一起动啦。我把你代码里的canMove改成targetEle了,你看下吧:

    <p id="p1" style="width:100px;height:100px;position:absolute;background:red"></p>
    <p id="p2" style="top:100px;width:100px;height:100px;position:absolute;background:blue"></p>
    <script type="text/javascript">
    ;(function(){
        var funcBody = {
            "addEvent" : addEvent,
            "getEventObj" : getEventObj,
            "getTarget" : getTarget,
            "preventDefault" : preventDefault,
            "removeEvent" : removeEvent,
            "getMouseDistance" : getMouseDistance,
            "mouseMoveFunc" : mouseMoveFunc,
            "moveElement" : moveElement,
            "getChangeValue" : getChangeValue,
            "setElementLT": setElementLT,
            "funcX" : funcX,
            "funcY" : funcY,
        }
    //绑定事件处理程序
    function addEvent(element,type,func){
        if(element.addEventListener){
            element.addEventListener(type,func,false);
        }else if(element.attachEvent){
            element.attachEvent("on"+type,func);
        }else{
            element["on"+type] = func;
        }
    }
    
    //获取event对象
    function getEventObj(event){
        return event?event:window.event;
    }
    
    //event的target事件目标
    function getTarget(event){
        return event.target||event.srcElement;
    }
    
    //取消元素默认行为
    function preventDefault(event){
        if(event.preventDefault){
            event.preventDefault();
        }else{
            event.returnValue = false;
        }
    }
    
    //移除事件处理程序
    function removeEvent(element,type,func){
        if(element.removeEventListener){
            element.removeEventListener(type,func,false);
        }else if(element.detachEvent){
            element.detachEvent("on"+type,func);
        }else{
            element["on"+type] = false;
        }
    }
    
        //鼠标拖拽
        function moveElement(element,referenceElement,direction,minDirection,maxDirection,func){
            funcBody.addEvent(element,"mousedown",getMouseDistance);
            funcBody.addEvent(document,"mouseup",mouseUpFunc);
            var returnValue = null;
            switch(direction){
                case "x": funcBody.addEvent(referenceElement,"mousemove",mouseMoveFunc(element,"x",minDirection,maxDirection,func));
                    break;
                case "y": funcBody.addEvent(referenceElement,"mousemove",mouseMoveFunc(element,"y",minDirection,maxDirection,func));
                    break;
                case "xy": funcBody.addEvent(referenceElement,"mousemove",mouseMoveFunc(element,"xy",minDirection,maxDirection,func));
                    break;
            }
        }
    
        var targetEle = false;  //设置标记用于判断是否点击了拖拽元素
        var mouseOffsetX = 0,
            mouseOffsetY = 0;
    
    //鼠标点击元素获取鼠标距元素左侧和顶部的距离
    function getMouseDistance(){
        event = funcBody.getEventObj(event);
        target = funcBody.getTarget(event);
        mouseOffsetX = event.pageX - target.offsetLeft;
        mouseOffsetY = event.pageY - target.offsetTop;
        targetEle = target
    }
    
    function getChangeValue(func){
        func();
    }
    
    //鼠标在元素上移动时执行某函数
    function mouseMoveFunc(element,direction,minDirection,maxDirection,func){
        return function(){
            if(element === targetEle){
                event = arguments[0]||window.event;
                var mouseX = 0;
                var mouseY = 0;
                mouseX = event.pageX - mouseOffsetX;
                mouseY = event.pageY - mouseOffsetY;
                funcBody.setElementLT(element,mouseX,mouseY,minDirection,maxDirection,direction);
                funcBody.getChangeValue(func);
            }
        }
    }
    
    //鼠标按键抬起时将canMove设为false
    function mouseUpFunc(){
        targetEle = false;
    }
    
    //设置元素的left和top值
    function setElementLT(element,x,y,min,max,deriction){
        switch(deriction){
            case "x":funcX(element,x,min,max);break;
            case "y":funcY(element,y,min,max);break;
            case "xy":funcX(element,x,min,max);
                      funcY(element,y,min,max);
                      break;
        }
    }
    function funcX(element,value,min,max){
        if(value<min){
            element.style.left = min + "px";
        }else if(value>max){
            element.style.left = max + "px";
        }else{
            element.style.left = value + "px";
        }
    }
    function funcY(element,value,min,max){
        if(value<min){
            element.style.top = min + "px";
        }else if(value>max){
            element.style.top = max + "px";
        }else{
            element.style.top = value + "px";
        }
    }
    window.funcBody = funcBody;
    })(window);
    
    var p1 = document.querySelector('#p1')
    funcBody.moveElement(p1, document, "x", 0, 500,function () {});
    
    var p2 = document.querySelector('#p2')
    funcBody.moveElement(p2, document, "y", 0, 500,function () {});
    </script>

    reply
    0
  • 高洛峰

    高洛峰2017-04-11 09:57:10

    看楼主这意思,应该是一个绑定对象的问题--你的方法有了,谁来调用这个方法。点击一个元素,有多个元素同时动,说明moveElement()这个方法的调用者this不是一个对象,而是一个对象组,你最好打印一下moveElement()方法的this是谁,就能看见问题出在哪里了

    reply
    0
  • Cancelreply