首页>前端教程>JavaScript教程

DOM基础9:拖拽原理

HTML5现在已经有了拖放的API,也就是说拖放已经成为了HTML5的标准,不过还是先了解一下JavaScript最原始的拖拽原理。

一、拖拽的基本原理

拖拽是基于三个事件触发的:

  • onmousedown : 选择元素

  • onmousemove : 移动元素

  • onmouseup   : 释放元素

oDiv.onmousedown = function (ev) {
    var ev= ev || event;
    // 获取到鼠标点击的时候到对象边缘的偏移值
    var disX = ev.clientX - this.offsetLeft;
    var disY = ev.clientY - this.offsetTop;

    document.onmousemove = function (ev) {
        var ev= ev || event;
        // 对象的坐标就是鼠标坐标减去点击时候的偏移值。
        oDiv.style.left = ev.clientX - disX + "px";
        oDiv.style.top = ev.clientY - disY + "px";
    }
    document.onmouseup = function () {
        document.onmousemove = document.onmouseup = null;
    }
    return false;
}

1、onmousedown:模拟开始拖拽事件。  

鼠标按键按下即发生  onmousedown  事件。  

获取鼠标位置,获取被拖拽元素的位置,记录两者之间的纵横坐标的差值。

2、对 document 元素绑定  onmousemove,onmouseup  事件。

为什么是对  document  绑定而不是对被拖动的元素绑定呢?

原因是如果对被拖动元素绑定的话,当鼠标拖动过快时,会导致鼠标与被拖动元素的脱离。      

onmousemove:模拟拖拽中事件。  

鼠标拖动即发生  onmousemove  事件。 

将被拖拽元素的  position  改成absolute绝对位置,这个可以通过  left  和  top  改变该元素的位置,从而使得该元素随着鼠标的拖拽而移动。

3、onmouseup:模拟拖拽结束事件。  

鼠标按键弹起即发生  onmouseup  事件。可以回收  onmousemove  和  onmousedown中的事件和变量,一次拖拽至此结束。

二、兼容性问题

如果拖拽对象上面有文字,或者文档中有别的文字或者图片被选中,会触发默认的拖拽行为。

解决方法:

标准:阻止默认行为

非标准ie:全局捕获

oDiv.onmousedown = function (ev) {
    var ev = ev || event;
    var disX = ev.clientX - this.offsetLeft;
    var disY = ev.clientY - this.offsetTop;
    // 为非标准的IE设置全局捕获,给一个元素设置全局捕获以后,那么这个元素就会监听后续发生的所有事件,当有事件发生的时候,就会被当前设置了全局捕获的元素所触发。
    if (oDiv.setCapture) {
    oDiv.setCapture();
}

    document.onmousemove = function (ev) {
    var ev = ev || event;
    oDiv.style.left = ev.clientX - disX + "px";
    oDiv.style.top = ev.clientY - disY + "px";
    }
    document.onmouseup = function () {
        document.onmousemove = document.onmouseup = null;
        //释放全局捕获 releaseCapture();
        if (oDiv.releaseCapture) {
        oDiv.releaseCapture();
        }
    }
    return false;
}

三、拖拽的封装

var oDiv = document.getElementById('div1');
    var oImg = document.getElementById('img1');
    
    drag(oImg);
    
    drag(oDiv);
    
    function drag(obj) {
        
        obj.onmousedown = function(ev) {
            var ev = ev || event;
            
            var disX = ev.clientX - this.offsetLeft;
            var disY = ev.clientY - this.offsetTop;
            
            if ( obj.setCapture ) {
                obj.setCapture();
            }
            
            document.onmousemove = function(ev) {
                var ev = ev || event;
                
                obj.style.left = ev.clientX - disX + 'px';
                obj.style.top = ev.clientY - disY + 'px';
            }
            
            document.onmouseup = function() {
                document.onmousemove = document.onmouseup = null;
                
                if ( obj.releaseCapture ) {
                    obj.releaseCapture();
                }
            }
            
            return false;
            
        }
        
    }

四、拖拽的范围限制

只需要实时计算拖拽的元素左、上边框距离左、上屏幕之间的距离就行了。如果把L和T的临界值L<0改成比如L<100,则可以实现磁性吸附的效果。

                    document.onmousemove = function (ev) {
                        var ev = ev || event;

                        // 获取元素拖拽中左边框距离可视区左边的距离。
                        var L = ev.clientX - disX;
                        // 获取元素拖拽中上边框距离可视区上边的距离。
                        var T = ev.clientY - disY;

                        if (L < 0) {
                            L = 0;
                        } else if (L > document.documentElement.clientWidth - obj.offsetWidth) {
                            L = document.documentElement.clientWidth - obj.offsetWidth;
                        }

                        if (T < 0) {
                            T = 0;
                        } else if (T > document.documentElement.clientHeight - obj.offsetHeight) {
                            T = document.documentElement.clientHeight - obj.offsetHeight;
                        }

                        obj.style.left = L + 'px';
                        obj.style.top = T + 'px';

                    }

五、碰撞

拖动一个元素去碰撞一个元素。

根据九宫格原理来实现。

            document.onmousemove = function(ev) {
                var ev = ev || event;
                
                var L = ev.clientX - disX;
                var T = ev.clientY - disY;
                
                var L1 = L;
                var R1 = L + obj.offsetWidth;
                var T1 = T;
                var B1 = T + obj.offsetHeight;
                
                var L2 = oImg.offsetLeft;
                var R2 = L2 + oImg.offsetWidth;
                var T2 = oImg.offsetTop;
                var B2 = T2 + oImg.offsetHeight;
                
                if ( R1 < L2 || L1 > R2 || B1 < T2 || T1 > B2 ) {
                    oImg.src = '1.jpg';
                } else {
                    oImg.src = '2.jpg';
                }
                
                obj.style.left = L + 'px';
                obj.style.top = T + 'px';
                
            }



点赞


2
保存到:

相关文章

Top