JS實現拖動div層移動

JS實現拖動p層移動

      在談到拖動p層之前,我們有必要來瞭解下 下面JS幾個屬性的區別—-  pageX,pageY,layerX,layerY,clientX,clientY,screenX,screenY,offsetX之間的區別!

 

     PageX: 鼠標在頁面上的位置,從頁面左上角開始,即是以頁面為參考點,不隨滑動條移動而變化.(隻有firefox等標準遊覽器特有,IE沒有)。

  clientX: 鼠標在頁面上可視區域的位置,從瀏覽器可視區域左上角開始,即是以瀏覽器滑動條此刻的滑動到的位置為參考點,隨滑動條移動 而變化.

 

這兩個最主要的區別是 在有滾動條的情況下,pageX是不隨滾動條變化而變化,clientx是在可視區域內的距離,不包括滾動條的距離。

 

  screenX: 鼠標在屏幕上的位置,從屏幕左上角開始,這個沒有任何爭議.

 

     offsetX和layerX

 

      offsetX   IE特有,鼠標相比較於觸發事件的元素的位置,以元素盒子模型的內容區域的左上角為參考點,如果有boder,可能出現負值。

 

      layerX:   firefox特有,鼠標相比較於當前坐標系的位置,即如果觸發元素沒有設置絕對定位或相對定位,以頁面為參考點,如果有,將改變參考坐標系,從觸發元素盒子模型的border區域的左上角為參考點 也就是當觸發元素設置瞭相對或者絕對定位後,layerX和offsetX就幸福地生活在一起^-^,幾乎相等,唯一不同就是一個從border為參考點,一個以內容為參考點,FF從border開始.

 

    pageX,pageY隻有firefox特有,IE沒有,所以要針對遊覽器兼容性寫個函數,Jquery源碼中 這樣寫的,

 

 

 

    所以我們也可以針對寫個公用的函數,代碼如下:

 

復制代碼

function pageXY(e) {

    var event = e || window.event;

 

    var doc = document.documentElement,

          body = document.body;

 

    // IE

    if (event.pageX == null && event.clientX !=  null ) {

        var doc = document.documentElement, 

            body = document.body;

 

            event.pageX = event.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) – ( doc && doc.clientLeft || body && body.clientLeft || 0 );

 

            event.pageY = event.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) – ( doc && doc.clientTop  || body && body.clientTop  || 0 );

 

            return {

                x : event.pageX,

                y : event.pageY

            }

        }

 

        // firefox

        return {

            x : event.pageX,

            y : event.pageY

        }

    }

復制代碼

offsetX 是IE特有的 layerX是firefox特有的,所以針對這兩個也可以寫個公用的函數 代碼如下:

 

復制代碼

function offsetXY(e) {

    var event = e || window.event;

    return {

         x:event.offsetX || event.layerX, 

                 y:event.offsetY || event.layerY 

    }

}

復制代碼

JSFiddle鏈接代碼如下:

 

 想看p層拖動的話 請點擊我!

 

拖動層的基本原理是:

 

  首先先來理解下 我們要在頁面上拖動某一塊 到 頁面上的另外一個位置 那麼肯定這塊元素是絕對定位的 並且 我們移動它時 是不斷的改變他們的top值和left值!再者 我們拖動它時候肯定要觸發事件!有 onmousedown事件!

 

  那麼我們現在是要計算的是 我們這個元素被拖動到頁面上的某個位置時的 左上標的位置X和Y。

 

      如下圖所示:

 

      

 

 

 

要計算元素的左上的x和y坐標 如上圖所示:就是指x = clientX-offsetX + "px"; y= clientY-offsetY + "px";

 

HTML和CSS代碼如下:

 

復制代碼

<p id="father" style="border:0px solid red;width:200px;">

    <p id="a" style="background:red;width:100px;height:100px">長,寬都是100px</p>

    <p id="b" style="border-top:0px solid red;background:yellow;width:100px;height:100px;margin-left:100px;"></p>

    </p>

<style> 

    #oDiv{ width:200px; height:200px; color:#fff;background:#00C; position:absolute; top:200px; left:200px; z-index:100;overflow:hidden;} 

 </style>

復制代碼

JS所有代碼如下:

 

復制代碼

function pageXY(e) {

    var event = e || window.event;

 

    var doc = document.documentElement,

        body = document.body;

 

    // IE

    if (event.pageX == null && event.clientX !=  null ) {

        var doc = document.documentElement, 

            body = document.body;

 

            event.pageX = event.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) – ( doc && doc.clientLeft || body && body.clientLeft || 0 );

 

            event.pageY = event.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) – ( doc && doc.clientTop  || body && body.clientTop  || 0 );

 

            return {

                x : event.pageX,

                y : event.pageY

            }

        }

 

        // firefox

        return {

            x : event.pageX,

            y : event.pageY

        }

    }

 

    function offsetXY(e) {

        var event = e || window.event;

        return {

             x:event.offsetX || event.layerX, 

                         y:event.offsetY || event.layerY 

        }

    }

    var $=function(id){

        return ("string"==typeof id) ? document.getElementById(id):id;

    };

    $('a').onmousemove = function(e){

        text(e);

    }

    $('b').onmousemove = function(e){

        text(e);

    }

    function text(e) {

        e = e || window.event;

        var offset = offsetXY(e),

            page = pageXY(e);

 

        var doc = document.documentElement,

            body = document.body;

                $("pageX").innerHTML= page.x;

        $("pageY").innerHTML= page.y;

        $("clientX").innerHTML=e.clientX;

        $("clientY").innerHTML=e.clientY;

        $("screenX").innerHTML=e.screenY;

        $("screenY").innerHTML=e.screenY;

        $("scrollTop").innerHTML=doc && doc.scrollTop;

        $("scrollLeft").innerHTML=doc && doc.scrollLeft;

        $("offsetX").innerHTML = offset.x;

        $("offsetY").innerHTML = offset.y;

    }

 

    window.onload = function () { 

            var oDiv = document.getElementById("oDiv");//oDiv必須使用CSS定位 

            oDiv.onmousedown = drag; 

            function drag(evt) { 

                evt = evt || window.event; 

                this.onmouseup = drop; 

                this.onmousemove = moveDiv; 

                this.offset = { 

                    x:evt.offsetX || evt.layerX, //layerX 和layerY是w3c標準的 offsetX 和 offsetY是IE標準的 

                    y:evt.offsetY || evt.layerY 

                }; 

            } 

            function moveDiv(evt) { 

                evt = evt || window.event; 

                this.style.left = evt.clientX-this.offset.x+"px"; 

                this.style.top = evt.clientY-this.offset.y+"px"; 

            } 

            function drop(evt) { 

                this.onmouseup = null; 

                this.onmousemove = null; 

            } 

        };        

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *