Hike News
Hike News

用滑鼠拖曳元素來移動位置

目的

之前有作過利用 HTML 拖曳功能建立 TODO-List 清單,但當時只是大約了解一下並不是十分了解,現在又有需要製作有拖曳功能的表單列表,卻忘了當時的作法,所以再來研究一下。

建立可拖曳的元素

要讓在 HTML 的元素具有拖曳的功能,只需要在元素加上 draggable="true" 就開啟功能,例:

1
2
<img src="main.png" draggable="true" />
<div id="book0011" draggable="true"></div>

建立元素的屬性

可使用的屬性除了可以在 HTML 也有 Javascript 可用的屬性,在 HTML 的是 事件處理器屬性 、Javascript 的是 事件 ,記的時候只需記一種就行了,因為 HTML 和 Javascript 的寫法差別就只差有沒有加 on 在前方。

可用的屬性

    • ondrag 、drag
      當一個可被拖曳的 元素 / 區塊 被點擊時觸發的事件執行

    • ondragenddragend
      點擊放開、放開滑鼠或按下 Esc 鍵時觸發的事件執行
      結束拖曳

    • ondragenterdragenter
      當被拖曳的 元素 / 區塊 移到作為目標的容器 ( 元素 / 區塊 ) 之上時,在元素移入容器的範圍內時觸發的事件執行
      這裡執行的是作為 容器 的元素 / 區塊,不是被拖移的元素 / 區塊

    • ondragexitdragexit
      當元素拖曳被放開後觸發的事件執行

    • ondragleavedragleave
      當元素被拖曳到容器範圍內之後離開容器範圍時所觸發的事件執行
      這裡事件執行的是作為 容器 的元素 / 區塊,不是被拖移的元素 / 區塊

    • ondragoverdragover

      當元素被拖曳到容器範圍內時觸發的事件執行
      這裡事件執行的是作為 容器 的元素 / 區塊,不是被拖移的元素 / 區塊

    • ondragstartdragstart
      當元素被拖曳時觸發的事件執行

    • ondropdrop
      當被拖曳的 元素 / 區塊 被移到作為目標的容器內後結束點擊時觸發的事件執行

使用方式

  • HTML

    • 屬性是要寫在被拖移的元素上
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <div id="div1"
    ondrop="drop(event)"
    ondragover="allowDrop(event)">
    <img src="main.png"
    draggable="true"
    ondragstart="drag(event)"
    id="drag1" /> <!-- 啟用拖放功能 -->
    </div>
    <div id="div2"
    ondrop="drop(event)"
    ondragover="allowDrop(event)"></div>
  • JS

    • [點擊時] - 設定當元素可被拖動時 ondragstart 和 取得的資料 setData()
      ondragstart 屬性調用了一個函數, drag( event ),它規定了被拖動的數據。
      dataTransfer.setData() 方法設置被拖數據的數據類型和值

      1
      2
      3
      4
      function drag (ev) {
      ev.dataTransfer.setData("Text",ev.target.id);
      }
      // 這個例子中,數據類型是"Text",值是可拖動元素的id
    • [按住不放] - 拖移元素 - ondragover
      ondragover 事件規定在何處放置被拖動的數據
      預設是無法將數據 / 元素放置到其他元素中
      如果需要設定可被置入的話,就必須要變更元素的預設值。

      1
      event.preventDefault()
    • [放開時] - 進行放置- ondrop屬性調用了一個函數,drop( event )
      當被拖移的元素被放開後就會執行 drop 事件

      1
      2
      3
      4
      5
      function drop (ev) {
      ev.preventDefault();
      var data=ev.dataTransfer.getData("Text");
      ev.target.appendChild(document.getElementById(data));
      }

實際例子

樣式

1
2
3
4
5
6
7
8
#div1, #div2 {
float:left;
width: 240px;
height: 240px;
padding:10px;
margin: 10px;
border:1px solid #aaaaaa;
}

功能設定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function allowDrop (ev) {
ev.preventDefault();
// 這是要配合 HTML 的 ondragover 一起使用,目的是要移除元素預設行為
}

function drag (ev) {
ev.dataTransfer.setData("Text",ev.target.id);
}

function drop (ev) {
ev.preventDefault(); // 移除預設行為
var data = ev.dataTransfer.getData("Text"); // 存取資料
ev.target.appendChild(document.getElementById(data));
}

dataTransfer.getData()

DataTransfer object’s getData(), setData() and clearData() methods.

畫面

1
2
3
4
5
6
7
8
9
10
11
<div id="div1"
ondrop="drop(event)"
ondragover="allowDrop(event)">
<img src="main.png"
draggable="true"
ondragstart="drag(event)"
id="drag1" /> <!-- 啟用拖放功能 -->
</div>
<div id="div2"
ondrop="drop(event)"
ondragover="allowDrop(event)"></div>

作為容器的屬性

1
2
3
id = "div1"     // 作為容器必要的固定名稱
ondrop = "drop(event)" // 放開時 = 將取得的資料置入
ondragover = "allowDrop(event)" // 在按住拖移期間 = 移除這個元素的預設行為

HTML 拖放 API 參考文件
HTML_Drag_and_Drop_API