JS頁面絕對定位的元素拖動
一.mousedown、mousemove和mouseup 拖著目標元素在頁面任意位置
如果要設定物體拖拽,那麼必須使用三個事件,並且這三個事件的使用順序不能顛倒。
1.onmousedown:滑鼠按下事件
2.onmousemove:滑鼠移動事件
3.onmouseup:滑鼠抬起事件
重點:
1、一定要絕對定位,脫離文件流才可以移動。
2、繫結拖拽的元素,移動和滑鼠鬆開後是對document的繫結,因為移動的是整個div。
3、點選:a= 獲取當前滑鼠座標、b =div距瀏覽器距離、c = 滑鼠在div內部距離=a-b。
移動:通過 a - c 建立滑鼠與div的關係,防止滑鼠超出div。
基本思路:
拖拽狀態 = 0滑鼠在元素上按下的時候{
拖拽狀態 = 1
記錄下滑鼠的x和y座標
記錄下元素的x和y座標
}
滑鼠在元素上移動的時候{
如果拖拽狀態是0就什麼也不做。
如果拖拽狀態是1,那麼
元素y = 現在滑鼠y - 原來滑鼠y + 原來元素y
元素x = 現在滑鼠x - 原來滑鼠x + 原來元素x
}
滑鼠在任何時候放開的時候{
拖拽狀態 = 0
}
貼上程式碼:
<div class="box" id="drag"></div>
.box{ position: absolute; width: 100px; height: 100px; background: purple; cursor: move; }
window.onload = function(){ var drag = document.getElementById('drag'); // //點選某物體時,用drag物件即可,move和up是全域性區域, // 也就是整個文件通用,應該使用document物件而不是drag物件(否則,採用drag物件時物體只能往右方或下方移動) drag.onmousedown = function(event){ var event = event || window.event; //相容IE瀏覽器 // 滑鼠點選物體那一刻相對於物體左側邊框的距離=點選時的位置相對於瀏覽器最左邊的距離-物體左邊框相對於瀏覽器最左邊的距離var diffX = event.clientX - drag.offsetLeft; var diffY = event.clientY - drag.offsetTop; if(typeof drag.setCapture !== 'undefined'){ drag.setCapture(); } document.onmousemove = function(event){ var event = event || window.event; var moveX = event.clientX - diffX; var moveY = event.clientY - diffY; if(moveX < 0){ moveX = 0 }else if(moveX > window.innerWidth - drag.offsetWidth){ moveX = window.innerWidth - drag.offsetWidth } if(moveY < 0){ moveY = 0 }else if(moveY > window.innerHeight - drag.offsetHeight){ moveY = window.innerHeight - drag.offsetHeight } drag.style.left = moveX + 'px'; drag.style.top = moveY + 'px' } document.onmouseup = function(event){ this.onmousemove = null; this.onmouseup = null; //修復低版本ie bug if(typeof drag.releaseCapture!='undefined'){ drag.releaseCapture(); } } } }
二.HTML5元素拖拽drag與拖放drop
元素拖拽
瀏覽器預設允許我們拖拽影象、文字以及連結
讓其它元素被拖動也是可以實現的
只需要在元素標籤上新增一個屬性
<div class="box1" draggable="true" id="source"></div>
拖拽事件
拖拽事件應該分為兩類
一類是被拖拽元素觸發的事件
另一類是拖放目標元素觸發的事件
<div class="box1" draggable="true" id="source"></div> <br> <div class="box2" id="target"></div>
拖拽元素
拖拽元素的時候,被拖拽元素會觸發以下事件
- dragstart
- drag
- dragend
當滑鼠點中元素並且開始移動時,就會觸發dragstart事件(類比mousedown)
拖拽過程中會持續不斷地觸發drag事件(類比mousemove)
鬆開滑鼠取消拖拽時就會觸發dragend事件(類比mouseup)
source.ondragstart = function(event){ var e = event || window.event console.log('開始拖拽'); } source.ondrag = function(){ console.log('拖拽中'); } source.ondragend = function(){ console.log('拖拽結束') }
目標元素
當拖拽的元素拖到一個目標元素上時,目標元素會觸發以下事件
- dragenter
- dragover
- dragleave
- drop
拖拽元素到目標上,就會觸發dragenter事件(類比mouseover)
當拖動元素在目標元素中,就會持續觸發dragover事件
離開目標元素,觸發dragleave事件(類比mouseout)
若拖放元素到了目標元素中(在目標元素中鬆開滑鼠),就會觸發drop事件而不會觸發dragleave事件
target.ondragenter = function(){ console.log('進入目標元素') } target.ondragover = function(event){ var event = event || window.event; console.log('在目標元素中拖拽'); event.preventDefault() } target.ondragleave = function(){ console.log('拖放離開目標元素') } target.ondrop = function(event){ console.log('拖放'); var e = event || window.event; }
注意:元素預設是不能夠拖放只要我們在目標元素的dragover事件中取消預設事件就可以解決問題
資料交換
資料交換的物件就是事件物件的屬性dataTransfer
dataTransfer的兩個核心方法是setData()和getData()
setData()用於設定資料,getData()用語接收資料
舉個拖放的例子:
<div class="box1" draggable="true" id="source"></div> <br> <div class="box2" id="target"></div>
.box1{
width: 100px;
height: 100px;
background: salmon
}
.box2{
width: 300px;
height: 300px;
border: 1px solid black
}
window.onload = function(){ var source = document.getElementById('source'); var target = document.getElementById('target'); source.ondragstart = function(event){ var e = event || window.event console.log('開始拖拽'); e.dataTransfer.setData('text',e.target.id); } target.ondragenter = function(){ console.log('進入目標元素') } target.ondragover = function(event){ var event = event || window.event; console.log('在目標元素中拖拽'); event.preventDefault() } target.ondragleave = function(){ console.log('拖放離開目標元素') } target.ondrop = function(event){ console.log('拖放'); var e = event || window.event var data = e.dataTransfer.getData('text'); e.target.appendChild(document.getElementById(data)); } }
拖拽設定
在dataTransfer中還有兩個重要的屬性
dropEffect和effectAllowed
dropEffect
dropEffect屬性值為字串,表示被拖動元素可以執行哪一種放置行為
要使用這個屬性,必須在dragenter事件處理函式中設定
- none 不能把元素拖放至此(除文字框外全部元素的預設值)
- move 移動到目標
- copy 複製到目標
- link 目標開啟拖動元素(拖動元素必須是連結並有URL)
effectAllowed
effectAllowed屬性值也是字串,表示允許拖動元素哪種dropEffect
要使用這個屬性,必須在dragst事件處理函式中設定
- uninitialized 沒有設定任何拖放行為
- none 不能由任何行為
- copy 僅允許dropEffect值為copy
- link 僅允許dropEffect值為link
- move 僅允許dropEffect值為move
- copyLink 允許dropEffect值為copy和link
- copyMove 允許dropEffect值為copy和move
- linkMove 允許dropEffect值為link和move
- all 允許任意dropEffect