一.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