文章出處

前面的話

  上一篇,我們介紹了元素拖拽的實現。但在實際應用中,常常需要為拖拽的元素限定范圍。而通過限定范圍,再增加一些輔助的措施,就可以實現磁性吸附的效果

 

范圍限定

  如果我們限定元素只可以在可視范圍內移動,那么就需要對其進行范圍限定

  首先,先要搞清楚是可視區域限定被拖拽元素

  左側范圍L0 = 0

  右側范圍R0 = document.documentElement.clientWidth

  上側范圍T0 = 0

  下側范圍B0 = document.documentElement.clientHeight

  元素的上下左右四邊分別為

  左側邊 L = offsetLeft

  右側邊 R = offsetLeft + offsetWidth

  上側邊 T = offsetTop

  下側邊 B = offsetTop + offsetHeight

function limitedRange(obj,fn){
    var L0 = 0;
    var R0 = document.documentElement.clientWidth;
    var T0 = 0;
    var B0 = document.documentElement.clientHeight;
    var L = obj.offsetLeft;
    var R = obj.offsetLeft + obj.offsetWidth;
    var T = obj.offsetTop;
    var B = obj.offsetTop + obj.offsetHeight;

    if(L >= L0 && R <= R0 && T >= T0 && B <= B0){
        fn(obj);
    }
}

 

拖拽范圍

  如果將范圍限定在拖拽元素上,則需要一些改變

  首先,限定條件并不是在范圍內執行什么,而是不在范圍內時,應該執行什么

  由于在拖拽實現中,已經獲取了元素距離可視區域左上角的X軸和Y軸的距離,所以不需要再通過offsetLeft和offsetTop進行重新獲取

<div id="test" style="height: 100px;width: 100px;background:pink;position:absolute;top:0;left:0;">測試文字</div>
<script>
function addEvent(target,type,handler){
    if(target.addEventListener){
        target.addEventListener(type,handler,false);
    }else{
        target.attachEvent('on'+type,function(event){
            return handler.call(target,event);
        });
    }
}
(function(){
    var x0,y0,x1,y1,isMoving;
    var ele = document.getElementById('test');
    var L0,R0,T0,B0,EH,EW;

    var mousedownHandler = function(e){
        e = e || event;
        //獲取元素距離定位父級的x軸及y軸距離
        x0 = this.offsetLeft;
        y0 = this.offsetTop;
        //獲取此時鼠標距離視口左上角的x軸及y軸距離
        x1 = e.clientX;
        y1 = e.clientY;
        //按下鼠標時,表示正在運動
        isMoving = true;
        //鼠標按下時,獲得此時的頁面區域
        L0 = 0;
        R0 = document.documentElement.clientWidth;
        T0 = 0;
        B0 = document.documentElement.clientHeight;
        //鼠標按下時,獲得此時的元素寬高
        EH = ele.offsetHeight;
        EW = ele.offsetWidth;
    }
    var mousemoveHandler = function(e){
        //如果沒有觸發down事件,而直接觸發move事件,則函數直接返回
        if(!isMoving){
            return;
        }
        e = e || event;
        //獲取此時鼠標距離視口左上角的x軸及y軸距離
        var x2 = e.clientX;
        var y2 = e.clientY;   
        //計算此時元素應該距離視口左上角的x軸及y軸距離
        var X = x0 + (x2 - x1);
        var Y = y0 + (y2 - y1);        
        /******范圍限定*******/
        //獲取鼠標移動時元素四邊的瞬時值
        var L = X;
        var R = X + EW;
        var T = Y;
        var B = Y + EH;
        //在將X和Y賦值給left和top之前,進行范圍限定。只有在范圍內時,才進行相應的移動
        //如果脫離左側范圍,則left置L0
        if(L < L0){X = L0;}
        //如果脫離右側范圍,則left置為R0
        if(R > R0){X = R0 - EW;}
        //如果脫離上側范圍,則top置T0
        if(T < T0){Y = T0;}
        //如果脫離下側范圍,則top置為B0
        if(B > B0){Y = B0 - EH;}

        //將X和Y的值賦給left和top,使元素移動到相應位置
        ele.style.left = X + 'px';
        ele.style.top = Y + 'px';
    }
    var mouseupHandler = function(e){
        //鼠標抬起時,表示停止運動
        isMoving = false;
        //釋放全局捕獲
        if(ele.releaseCapture){
            ele.releaseCapture();
        }
    }
    var preventDefaultHandler = function(e){
        e = e || event;
        if(e.preventDefault){
            e.preventDefault();
        }else{
            e.returnValue = false;
        }
        //IE8-瀏覽器阻止默認行為
        if(ele.setCapture){
            ele.setCapture();
        }

}
addEvent(ele,'mousedown',mousedownHandler);
addEvent(ele,'mousedown',preventDefaultHandler);
addEvent(document,'mousemove',mousemoveHandler)
addEvent(document,'mouseup',mouseupHandler)

})();
</script>

磁性吸附

  磁性吸附只需要在范圍限定的基礎上,做一些修改即可

  下列代碼中,只要元素的四邊,距離可視區域范圍的四邊小于50px,則元素將直接吸附對應的邊上

<div id="test" style="height: 100px;width: 100px;background:pink;position:absolute;top:0;left:0;">測試文字</div>
<script>
function addEvent(target,type,handler){
    if(target.addEventListener){
        target.addEventListener(type,handler,false);
    }else{
        target.attachEvent('on'+type,function(event){
            return handler.call(target,event);
        });
    }
}
(function(){
    var x0,y0,x1,y1,isMoving;
    var ele = document.getElementById('test');
    var L0,R0,T0,B0,EH,EW;

    var mousedownHandler = function(e){
        e = e || event;
        //獲取元素距離定位父級的x軸及y軸距離
        x0 = this.offsetLeft;
        y0 = this.offsetTop;
        //獲取此時鼠標距離視口左上角的x軸及y軸距離
        x1 = e.clientX;
        y1 = e.clientY;
        //按下鼠標時,表示正在運動
        isMoving = true;
        //鼠標按下時,獲得此時的頁面區域
        L0 = 0;
        R0 = document.documentElement.clientWidth;
        T0 = 0;
        B0 = document.documentElement.clientHeight;
        //鼠標按下時,獲得此時的元素寬高
        EH = ele.offsetHeight;
        EW = ele.offsetWidth;
    }
    var mousemoveHandler = function(e){
        //如果沒有觸發down事件,而直接觸發move事件,則函數直接返回
        if(!isMoving){
            return;
        }
        e = e || event;
        //獲取此時鼠標距離視口左上角的x軸及y軸距離
        var x2 = e.clientX;
        var y2 = e.clientY;   
        //計算此時元素應該距離視口左上角的x軸及y軸距離
        var X = x0 + (x2 - x1);
        var Y = y0 + (y2 - y1);        
        /******磁性吸附*******/
        //獲取鼠標移動時元素四邊的瞬時值
        var L = X;
        var R = X + EW;
        var T = Y;
        var B = Y + EH;
        //在將X和Y賦值給left和top之前,進行范圍限定。只有在范圍內時,才進行相應的移動
        //如果到達左側的吸附范圍,則left置L0
        if(L - L0 < 50){X = L0;}
        //如果到達右側的吸附范圍,則left置為R0
        if(R0 - R < 50){X = R0 - EW;}
        //如果到達上側的吸附范圍,則top置T0
        if(T - T0 < 50){Y = T0;}
        //如果到達右側的吸附范圍,則top置為B0
        if(B0 - B < 50){Y = B0 - EH;}

        //將X和Y的值賦給left和top,使元素移動到相應位置
        ele.style.left = X + 'px';
        ele.style.top = Y + 'px';
    }
    var mouseupHandler = function(e){
        //鼠標抬起時,表示停止運動
        isMoving = false;
        //釋放全局捕獲
        if(ele.releaseCapture){
            ele.releaseCapture();
        }
    }
    var preventDefaultHandler = function(e){
        e = e || event;
        if(e.preventDefault){
            e.preventDefault();
        }else{
            e.returnValue = false;
        }
        //IE8-瀏覽器阻止默認行為
        if(ele.setCapture){
            ele.setCapture();
        }

}
addEvent(ele,'mousedown',mousedownHandler);
addEvent(ele,'mousedown',preventDefaultHandler);
addEvent(document,'mousemove',mousemoveHandler)
addEvent(document,'mouseup',mouseupHandler)

})();
</script>


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()