H5 拖拽操作
前言
在原生H5中,可以通過提供的api實現在網頁內元素的拖拽操作。相對於傳統的寫法更加的簡單。
而想要實現拖拽,主要需要進行兩個方面的工作,第一是給元素設置draggable='true'
屬性,img和a標簽是默認允許拖拽的。第二是編寫拖拽相關的事件處理函數。
拖拽主要的過程
在整個拖拽的過程中,可以把行為分成兩個部分,一部分是關於拖拽元素的操作,另外一個部分是關於拖拽元素最終放置的容器上的操作。
當拖拽元素時,拖拽事件執行的流程如下:
dragstart -> drag -> dragend
dragstart
事件的觸發時機是在按住鼠標開始拖動的時候,只會觸發一次。
drag
事件是在按住鼠標拖動的過程中觸發,是屬於持續觸發的狀態。
dragend
事件是在釋放鼠標之后觸發,此時無論是已經將目標放在了有效的位置還是放在了無效的位置上,都會觸發這個事件。
放置元素主要經歷的過程
當我們放置元素時,需要經歷的事件變化流程如下:
dragenter -> dragover -> drop
dragenter
事件,當拖拽元素被拖拽到了目標元素上,就會被觸發
dragover
事件,當拖拽的元素被拖拽到了目標元素上並且在目標元素上移動時,就會持續性的觸發。
drop
事件,拖拽的元素放在了目標元素身上的時候會被觸發。
tip: 這當中在
dragover
事件之后還包含了dragleave
事件,當元素離開了目標元素時觸發。
整體的拖拽流程如下:
dragstart->drag->dragenter->dragover->dragleave->drop->dragend
例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.box {
width:100px;
height: 100px;
background-color: lightblue;
}
#content {
width:300px;
height: 300px;
border:2px solid #222;
position: absolute;
right:0;
top:0;
}
</style>
</head>
<body>
<div class="box" draggable='true'></div>
<div id="content"></div>
</body>
<script type="text/javascript">
var box = document.getElementsByTagName('div')[0];
var content = document.getElementById('content');
box.ondragstart = function() {
console.log(1111)
event.dataTransfer.setData('Text',this.className);
}
box.ondrag = function() {
console.log(2222)
}
box.ondragend = function() {
console.log(3333)
}
content.ondragenter = function() {
console.log('enter')
}
content.ondragover = function() {
console.log('over')
event.preventDefault();
}
content.ondrop = function() {
console.log('drop')
var data = event.dataTransfer.getData('Text');
this.appendChild(document.getElementsByClassName(data)[0])
}
</script>
</html>
實現的效果:
tip: 想要順利的完成拖拽,需要在
dragover
事件里阻止默認行為,event.preventDefault();
火狐的兼容問題
在火狐瀏覽器里,如果僅僅給元素設置draggable='true'
這個屬性,是無法完成拖拽的[谷歌沒有問題]。
要解決這個問題必須為拖拽元素綁定dragstart事件處理函數,並且在該函數中調用event.dataTransfer.setData函數
// box 是拖拽的元素
box.ondragstart = function() {
console.log(1111)
event.dataTransfer.setData('Text',this.className);
}
同時,在火狐瀏覽器當中,當我們直接進行拖拽的時候,發現會產生打開新選項卡的現象,解決辦法是在所有的容器代碼里,都加上阻止默認行為的代碼:
event.preventDefault();
event.stopPropagation();