HTML元素拖拽功能的實現

目錄

1  需要了解的知識點

1.1  offset(偏移量)

1.2  client(客戶區)

1.3  scroll(滾動區域)

1.4  鼠標事件對象(mouseEvent)的一些屬性

2  示例演示

2.1  元素水平拖拽效果實現

2.2  元素垂直拖拽效果實現

2.3  元素任意方向拖拽效果實現

3  參考文獻


1  需要了解的知識點

1.1  offset(偏移量)

定義:元素在屏幕上佔用的所有的可見的空間。

元素可見的大小由其高度、寬度決定,包括所有內邊距、滾動條和邊框大小四個屬性

offsetHeight:元素正在垂直方向上佔用的大小空間,單位爲px,不包括margin值。只讀屬性。

offsetWidth:元素在水平方向上佔用的大小空間,單位爲px,不包括margin值。只讀屬性。

offsetLeft:元素的左外邊框至包含元素的左內邊框之間的距離,單位爲px。只讀屬性。

offsetTop:元素的上外邊框至包含元素的上內邊框之間的像素距離,單位爲px。只讀屬性。

offsetParent:是一個元素最近的並且是定位過(relative || absolute)的父元素,如果沒有父元素或者是父元素中沒有一個是定位過的,返回值就是body元素。只讀屬性。

element.offsetLeft和element.offsetTop取值問題,分多種情況:

如果element是body的直接子元素,返回值則是element距離body左側或頂部的距離;

如果element不是body的直接子元素,在父元素進行定位(relative或absolute)的情況下,各瀏覽器返回值都是element距離父元素左側或者是頂部的距離(唯一的區別就是chrome沒有把邊框計算進去,IE、firefox都計算進去了);

如果element不是body的直接子元素,父元素也沒有進行定位的情況下,各瀏覽器返回的直接是element元素距body的距離。

從上面可以看出offsetLeft、offsetTop返回的值就是element到offsetParent的距離,這個offsetParent是什麼元素要看ele的父元素有沒有進行定位(relative、absolute)。

1.2  client(客戶區)

定義:元素的客戶區大小(client dimension)指的是元素內容及其內邊距所佔距的空間大小。

clientWidth:元素內容區寬度 + 左右內邊距寬度,單位爲px。內聯元素以及沒有 CSS 樣式的元素的clientWidth屬性值爲 0。該屬性包括內邊距,但不包括垂直滾動條(如果有)、邊框和外邊距。只讀屬性。

clientHeight:元素內容區高度 + 上下內邊距高度,單位爲px。內聯元素以及沒有 CSS 樣式的元素的clientHight屬性值爲 0。該屬性包括內邊距,但不包括水平滾動條(如果有)、邊框和外邊距。只讀屬性。

clientLeft:表示一個元素的左邊框的寬度,單位爲px。如果元素在左側(右側滾動條不算)有垂直滾動條,則該屬性包括滾動條的寬度。clientLeft不包括左外邊距和左內邊距。只讀屬性。

clientTop:表示一個元素的上邊框的寬度,單位爲px。如果元素在頂部(底部滾動條不算)有水平滾動條,則該屬性包括滾動條的寬度。clientTop不包括上外邊距和上內邊距。只讀屬性。

1.3  scroll(滾動區域)

我們一般看到的默認滾動條的寬度是17px。

滾動大小:指的是包含滾動內容的元素的大小。

scrollHeight: 在沒有滾動條的情況下,元素內容的總高度,單位爲px。該尺寸包括元素的padding,但不包括元素的border、margin和水平滾動條寬度(如果存在)。

scrollWidth:在沒有滾動條的情況下,元素內容的總寬度,單位爲px。該尺寸包括元素的padding,但不包括元素的border、margin和垂直滾動條的寬度(如果存在)。

scrollLeft:被隱藏在內容區域左側的像素值,通俗的解釋就是元素水平滾動條到元素左邊的距離。通過設置這個屬性值可以改變元素的滾動位置。

scrollTop:被隱藏在內容區域上方的像素值,通俗的解釋就是元素垂直滾動條到元素上方的距離。通過設置這個屬性值可以改變元素的滾動位置。

1.4  鼠標事件對象(mouseEvent)的一些屬性

mEvent.clientX:返回鼠標觸點相對於瀏覽器可見視區(或有效區域)左邊沿的的X座標,不包括任何滾動偏移,單位爲px。這個值會根據用戶對可見視區的縮放行爲而發生變化。

mEvent.clientY:返回鼠標觸點相對於瀏覽器可見視區(或有效區域)上邊沿的的Y座標,不包括任何滾動偏移,單位爲px。這個值會根據用戶對可見視區的縮放行爲而發生變化。

mEvent.pageX:鼠標觸點相對於HTML文檔左邊沿的的X座標,單位爲px。和clientX 屬性不同,這個值是相對於整個html文檔的座標,和用戶滾動位置無關。因此當存在水平滾動的偏移時,這個值包含了水平滾動的偏移。

mEvent.pageY:鼠標觸點相對於HTML文檔上邊沿的的Y座標,單位爲px。和clientY 屬性不同,這個值是相對於整個html文檔的座標,和用戶滾動位置無關。因此當存在垂直滾動的偏移時,這個值包含了垂直滾動的偏移。

mEvent.screenX:返回鼠標觸點相對於屏幕左邊沿的X座標,單位爲px。不包含頁面滾動的偏移量。

mEvent.screenY:返回鼠標觸點相對於屏幕上邊沿的Y座標,單位爲px。不包含頁面滾動的偏移量。

mEvent.offsetX:當鼠標事件發生時,鼠標觸點距離事件源元素左側的X軸方向上的距離,單位爲px。

mEvent.offsetY:當鼠標事件發生時,鼠標觸點距離事件源元素頂部的Y軸方向上的距離,單位爲px。

2  示例演示

2.1  元素水平拖拽效果實現

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="blackSquare" style="position: absolute; width:50px; height:50px; background-color: black;cursor: pointer;"></div>
</body>
<script>
    window.onload = () => {
        //獲取拖拽實驗對象
        let el=document.getElementById("blackSquare");
        //在該對象上綁定鼠標點擊事件
        el.onmousedown = (e) => {
            //鼠標按下,計算鼠標觸點距離元素左側的距離
            let disX = e.clientX - el.offsetLeft;
            document.onmousemove = function (e) {
              //計算需要移動的距離
              let t = e.clientX - disX;
              //移動當前元素
              if (t >= 0 && t <= window.innerWidth - el.offsetWidth) {
                el.style.left = t + 'px';
              } 
            };
            //鼠標鬆開時,註銷鼠標事件,停止元素拖拽。
            document.onmouseup = function (e) {
                document.onmousemove = null;
                document.onmouseup = null;
            };
        }   
    }
</script>
</html>

2.2  元素垂直拖拽效果實現

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="blackSquare" style="position: absolute; width:50px; height:50px; background-color: black;cursor: pointer;"></div>
</body>
<script>
    window.onload = () => {
        //獲取拖拽實驗對象
        let el=document.getElementById("blackSquare");
        //在該對象上綁定鼠標點擊事件
        el.onmousedown = (e) => {
            //鼠標按下,計算鼠標觸點距離元素左側的距離
            let disY = e.clientY - el.offsetTop;
            document.onmousemove = function (e) {
              //計算需要移動的距離
              let t = e.clientY - disY;
              //移動當前元素
              if (t >= 0 && t <= window.innerHeight - el.offsetHeight) {
                el.style.top = t + 'px';
              } 
            };
            //鼠標鬆開時,註銷鼠標事件,停止元素拖拽。
            document.onmouseup = function (e) {
                document.onmousemove = null;
                document.onmouseup = null;
            };
        }   
    }
</script>
</html>

2.3  元素任意方向拖拽效果實現

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="blackSquare" style="position: absolute; width:50px; height:50px; background-color: black;cursor: pointer;"></div>
</body>
<script>
    window.onload = () => {
        //獲取拖拽實驗對象
        let el=document.getElementById("blackSquare");
        //在該對象上綁定鼠標點擊事件
        el.onmousedown = (e) => {
            //鼠標按下,計算鼠標觸點距離元素左側和頂部的距離
            let disX = e.clientX - el.offsetLeft;
            let disY = e.clientY - el.offsetTop;
            document.onmousemove = function (e) {
              //計算需要移動的距離
              let tX = e.clientX - disX;
              let tY = e.clientY - disY;
              //移動當前元素
              if (tX >= 0 && tX <= window.innerWidth - el.offsetWidth) {
                el.style.left = tX + 'px';
              } 
              if (tY >= 0 && tY <= window.innerHeight - el.offsetHeight) {
                el.style.top = tY + 'px';
              } 
            };
            //鼠標鬆開時,註銷鼠標事件,停止元素拖拽。
            document.onmouseup = function (e) {
                document.onmousemove = null;
                document.onmouseup = null;
            };
        }   
    }
</script>
</html>

3  參考文獻

https://www.cnblogs.com/ivan5277/p/9811242.html

https://www.jianshu.com/p/2a82ed72a192

https://developer.mozilla.org/zh-CN/docs/Web/API/Element

https://developer.mozilla.org/zh-CN/docs/Web/API/Touch

https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章