Drag and Drop event
HTML5現在有支援了將文字或圖片拖放到其他地方放置的功能,
我從w3schools找到一個很讚的範例來說明所有事件的應用。
<!DOCTYPE HTML> <html> <head> <style> .droptarget { float: left; width: 100px; height: 35px; margin: 15px; padding: 10px; border: 1px solid #aaaaaa; } </style> </head> <body> <p>Drag the p element back and forth between the two rectangles:</p> <div class="droptarget"> <p draggable="true" id="dragtarget">Drag me!</p> </div> <div class="droptarget"></div> <p style="clear:both;"><strong>Note:</strong> drag events are not supported in Internet Explorer 8 and earlier versions or Safari 5.1 and earlier versions.</p> <p id="demo"></p> <script> /* Events fired on the drag target */ document.addEventListener("dragstart", function (event) { // The dataTransfer.setData() method sets the data type and the value of the dragged data //save被抓取元素的id(為string值) event.dataTransfer.setData("Text", event.target.id); // Output some text when starting to drag the p element document.getElementById("demo").innerHTML = "Started to drag the p element."; // Change the opacity of the draggable element event.target.style.opacity = "0.4"; }); // While dragging the p element, change the color of the output text document.addEventListener("drag", function (event) { document.getElementById("demo").style.color = "red"; }); // Output some text when finished dragging the p element and reset the opacity document.addEventListener("dragend", function (event) { document.getElementById("demo").innerHTML = "Finished dragging the p element."; event.target.style.opacity = "1"; }); /* Events fired on the drop target */ // When the draggable p element enters the droptarget, change the DIVS's border style document.addEventListener("dragenter", function (event) { if (event.target.className == "droptarget") { event.target.style.border = "3px dotted red"; } }); // By default, data/elements cannot be dropped in other elements. To allow a drop, we must prevent the default handling of the element document.addEventListener("dragover", function (event) { event.preventDefault(); }); // When the draggable p element leaves the droptarget, reset the DIVS's border style document.addEventListener("dragleave", function (event) { if (event.target.className == "droptarget") { event.target.style.border = ""; } }); /* On drop - Prevent the browser default handling of the data (default is open as link on drop) Reset the color of the output text and DIV's border color Get the dragged data with the dataTransfer.getData() method The dragged data is the id of the dragged element ("drag1") Append the dragged element into the drop element */ document.addEventListener("drop", function (event) { event.preventDefault(); if (event.target.className == "droptarget") { document.getElementById("demo").style.color = ""; event.target.style.border = ""; //取得被抓取元素的id的document物件,並附加在div元素裡 var data = event.dataTransfer.getData("Text"); event.target.appendChild(document.getElementById(data)); } }); </script> </body> </html>
事件間的時序關係應該如下圖

一些事件與屬性的說明如下
一、dragstart事件
該事件交給了DragEven介面處理,當一元素被抓取時觸發。
二、drag事件
該事件交給了DragEven介面處理,注意drag事件每350 milliseconds會觸發一次。
三、dragend事件
該事件交給了DragEven介面處理,當拖曳一元素被滑鼠或鍵盤放開的時候觸發。
四、dragenter事件
該事件交給了DragEven介面處理,當被抓取的元素離開或進入某一物件的範圍時被觸發。
五、dragover事件
該事件交給了DragEven介面處理,當一個元素被拖到有效的放置目標時觸發。
由於元素預設值是不能被拖進另一個元素裡,所以這事件專門用來解鎖此功能。
document.addEventListener("dragover", function (event) { event.preventDefault(); });
以下示範解鎖前與未解鎖前的差異,
未解鎖前

解鎖後

六、dragleave事件
該事件交給了DragEven介面處理,當被拖曳的元素離開原本的地方時觸發。
七、dragexit事件
該事件交給了DragEven介面處理,目前瀏覽器都不支援。
八、drop事件
該事件交給了DragEven介面處理,當一個元素被放置時觸發。
當一個圖片被抓取放置時預設是打開該圖片。
九、draggable屬性
是一個HTML屬性,用來表示一個包含元素的文字是否可當成物件來拖動。
<div class="droptarget"> <p draggable="true" id="dragtarget">Drag me!</p> </div>
十、DataTransfer屬性
DataTransfer是DragEven介面的屬性,常用的屬性與方法有,
DataTransfer.dropEffect、DataTransfer.effectAllowed、DataTransfer.files、
DataTransfer.items、DataTransfer.types、DataTransfer.clearData()、DataTransfer.getData()、
DataTransfer.setData()、DataTransfer.setDragImage()
範例如下
document.addEventListener("dragstart", function (event) { // The dataTransfer.setData() method sets the data type and the value of the dragged data //save被抓取元素的id(為string值) event.dataTransfer.setData("Text", event.target.id); // Output some text when starting to drag the p element document.getElementById("demo").innerHTML = "Started to drag the p element."; // Change the opacity of the draggable element event.target.style.opacity = "0.4"; });
十一、應用範例
最後附上以Drag and Drop技術應用在圖片上傳的範例,就不多做說明了,
此範例有前後端,程式需放在IIS上跑。
前端
@section header{
<style>
.dragleave {
width: 100%;
height: 100px;
border: 1px solid #000000;
}
.dragenter {
width: 100%;
height: 100px;
border: 5px dashed #808080;
text-align: center;
padding-top: 25px;
color: #808080;
font: 26px 微軟正黑體,sans-serif;
}
.displayNone {
display: none;
}
</style>
}
<div id="dragUpLoad" class="dragleave">
</div>
<div id="result">
</div>
<div class="progress text-center displayNone">
<div id="upload_progress" class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="" aria-valuemin="0" aria-valuemax="100">
</div>
</div>
@section scripts{
<script>
var dragUpLoad = document.getElementById("dragUpLoad");
dragUpLoad.addEventListener("dragenter", function myfunction(e) {
this.className = "dragenter";
this.innerText = "上傳";
});
dragUpLoad.addEventListener("dragleave", function myfunction(e) {
this.className = "dragleave";
this.innerText = "";
});
dragUpLoad.addEventListener("dragover", function myfunction(e) {
e.preventDefault();
});
dragUpLoad.addEventListener("drop", function myfunction(e) {
e.preventDefault();
//顯示進度條
document.getElementsByClassName("progress")[0].setAttribute("class","progress text-center");
/*FormData*/
var file = e.dataTransfer.files[0];
var formData = new FormData();
formData.append("userfile", file);
/*XMLHttpRequest*/
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "@Url.Action("Index")", true);
//註冊處理中委派
xhttp.upload.onprogress = function myfunction(e) {
if (e.lengthComputable) {
var intComplete = (e.loaded / e.total) * 100;
document.getElementById("upload_progress").innerHTML = Math.round(intComplete) + '%';
document.getElementById("upload_progress").style.width = Math.round(intComplete) + '%';
}
}
//註冊完成後委派
xhttp.upload.onload = function myfunction(e) {
//刪除上傳區域
document.getElementById("dragUpLoad").remove();
//隱藏進度條
document.getElementsByClassName("progress")[0].setAttribute("class", "progress text-center displayNone");
}
xhttp.onloadend = function myfunction() {
//顯示圖片
var arrData = JSON.parse(xhttp.response);
var img = new Image();
img.src = arrData;
img.className = 'image';
img.style = "width:100%";
document.getElementById("result").appendChild(img);
}
xhttp.send(formData);
});
</script>
}
後端
using System.Web.Mvc;
using System.Web;
using System.IO;
using Newtonsoft.Json;
namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(HttpPostedFileBase userfile)
{
try
{
string fileName = System.IO.Path.GetFileName(userfile.FileName);
string path = System.IO.Path.Combine(Server.MapPath("/"), fileName);
if (Directory.Exists(path))
{
Directory.Delete(path);
}
userfile.SaveAs(path);
return Content(JsonConvert.SerializeObject("/"+ fileName), "application/json");
}
catch (System.Exception)
{
throw;
}
}
}
}
參考資料: