导航菜单
  • 首页
  • 首页>前端万博manbext备用网址>JavaScript万博manbext备用网址

    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';
                    
                }



    点赞


    3
    保存到:

    相关文章

    发表评论:

    ◎请发表你卖萌撒娇或一针见血的评论,严禁小广告。

    Top