HTML5中的拖放功能 | 打卡每天一份勸退技能
技術標籤:前端程式設計WEB前端cssjavascriptvue.jshtmlhtml5
前言
如果這篇文章有幫助到你,❤️關注+點贊❤️鼓勵一下作者,接收好挑戰了嗎?筆芯❤️~
知識點
拖拽的體驗,你享受過嗎,在HTML5
之前,可以使用事件mousedown,mousemove,mouseup
巧妙實現頁面的拖放操作,但注意拖放的操作範圍只是侷限在瀏覽器內部。
而HTML5
的拖放API
功能直接實現拖放操作,而且拖放的範圍已經超出瀏覽器的邊界,HTML5
提供的檔案api
支援拖拽多個檔案並上傳。
要學會掌握html5
中的拖放api
和 檔案api
,游標拖放事件,從web
網頁上訪問本地檔案系統。
拖放api
在html5
中的拖放api
重點:
第一,為頁面元素提供了拖放特性;
第二,為游標增加了拖放事件;
第三,提供了用於儲存拖放資料的DataTransfer
物件
draggable特性
draggable
特性用於定義元素是否允許使用者拖放:提供了三個值
true,false,auto
把元素變成可以拖放的:
<div draggable="true"></div>
複製程式碼
img
元素和a
元素預設是可以拖放的
游標拖放事件
在html5
中提供了7個與拖放相關的游標事件:
按照時間的順序:
第一,開始拖拽時觸發的事件,事件的作用物件是被拖拽的元素
dragstart
事件
第二,拖放過程中觸發的事件,事件的作用物件是被拖拽的元素-drag
事件
第三,在拖放的元素進入本元素的範圍內時觸發,事件的作用物件是拖放過程中游標經過的元素-dragenter
元素
第四,在拖放的元素正在本元素的範圍內移動時觸發,事件的作用物件是拖放過程中游標經過的元素-dragover
元素
第五,在拖放的元素離開本元素的範圍時觸發,事件的作用物件是拖放過程中游標經過的元素-dragleave
元素
第六,在拖放的元素被拖放到本元素中時觸發,事件的作用物件是拖放的目標元素-drop
元素
第七,在拖放操作結束時觸發,事件的作用物件是被拖拽的元素-dragend
事件
DataTransfer物件
在html5
中提供了DataTransfer
物件,用來支援拖拽資料的儲存。
實現拖放的過程中資料交換。
DataTransfer
物件:
屬性
第一,dropEffect
屬性:用來設定或獲取拖拽操作的型別 和 要顯示的游標型別。
如果該操作的效果與起初設定的effectAllowed
效果不符,則拖拽操作失敗。可以設定修改,包含值可為:none, copy, link, move
第二,effectAllowed
屬性:用來設定或獲取資料傳送操作可應用於操作物件的源元素,指定值:none, copy, copyLink, copyMove, link, linkMove, move, all 和 uninitialized
第三,type
屬性:獲取在dragstart
事件出發時為元素儲存資料的格式,如果是外部檔案的拖拽,則返回Files
。
第四,files
屬性:獲取儲存在DataTransfer
物件中的正在拖放的檔案列表FileList
,可以使用陣列的方式去遍歷。
方法
第一,clearData()
方法:清除DataTransfer
物件中存放的資料:
clearData([sDataFormat])
複製程式碼
[sDataFormat]
為可選引數,取值可能為:Text,URL,File,HTML,Image,
設定後,可刪除指定格式的資料,如果省略該引數,則清除全部資料。
第二,setData()
方法:向記憶體中的DataTransfer
物件新增指定格式的資料:
setData([sDataFormat],[data])
複製程式碼
第三,getData()
方法:從記憶體的DataTransfer
物件中獲取資料
getData([sDataFormat])
複製程式碼
第四,setDragImage()
方法:設定拖放時跟隨游標移動的圖片
setDragImage([imgElement],[x],[y])
複製程式碼
[imgElement]
表示圖片物件,[x],[y]
分別表示相對於游標位置的橫座標和縱座標
第五,addElement()
方法:新增一起跟隨拖放的元素,如果想讓某個元素跟隨被拖動元素一起被拖放,則使用此方法
addElement([element])
複製程式碼
[element]
表示一起跟隨拖動的元素物件
示例
// 源元素
<div id="dragSource" draggable="true">
拖動
<img src="images/dadaqianduan.png" width="50" height="50">
</div>
// 目標元素
<div id="dropTarget"></div>
複製程式碼
新增ondragstart
監聽事件,給拖放的源元素新增ondragstart
監聽事件,在事件觸發時把源元素裡的內容追加至dataTransfer
物件中。
最後,把新增監聽事件的處理函式DragStart()
追加到window.onload
事件中。
function DragStart() {
var source = document.getElementById("dragSource"); // 拖放源元素
// 監聽dragstart事件,作用在源元素上
source.addEventListener("dragstart", function(e){
e.dataTransfer.setData('text/plain', e.target.innerHTML);
// 向dataTransfer物件中追加資料
e.dataTransfer.effectAllowed="copy";
},false);
}
// 新增函式DragStart到window.onload監聽事件
window.addEventListener("load",DragStart,false);
複製程式碼
新增dragover
監聽事件,給拖放的目標元素新增dragover
監聽事件,在事件觸發時改變目標元素的樣式,並遮蔽瀏覽器的預設處理事件。
把新增監聽事件的處理函式DragOver()
追加到window.onload
事件中,對於目標元素preventDefault()
,必須取消瀏覽器的預設處理,否則將無法實現拖放功能。
function DragOver() {
// 拖放目標元素
var target = document.getElementById('dropTarget');
// 監聽dragover事件,作用在目標元素上
target.addEventListener("dragover", function(e){
// 改變樣式
this.className = "dragover";
// 取消瀏覽器的預設處理
e.preventDefault();
},false);
}
// 新增函式DragStart到window.onload監聽事件
window.addEventListener("load", DragOver, false);
複製程式碼
給拖放的目標元素新增ondrop
監聽事件,事件觸發時獲取dataTransfer
物件中的資料,並追加到目標元素中,同時還還原了樣式。
把新增監聽事件的處理函式Drop()
追加到window.onload
事件中。
function Drop(){
// 拖放目標元素
var target = document.getElementById('dropTarget');
// 監聽drop事件,作用在目標元素上
target.addEventListener('drop',function(e){
var data = e.dataTransfer.getData('text/plain');
//取得dataTransfer物件中的資料
this.innerHTML += data;
e.dataTransfer.dropEffect = "copy";
// 還原樣式
this.className=""
},false);
}
// 新增函式DragStart到window.onload監聽事件
window.addEventListener("load",Drop, false);
複製程式碼
檔案api
在html5
中提供了關於檔案操作的檔案api,通過程式設計方式選擇和訪問檔案資料。
如:FileList
物件,File
物件,Blob
介面,FileReader
介面
增加的標籤特性
在html5
中file
型別的表單元素增加了multiple
特性和accept
特性
multiple特性
multiple
特性可允許使用者同時選擇多個上傳檔案。
<input type="file" multiple/>
複製程式碼
得到一個
FileList
物件,是一個File
物件的列表
accept特性
規定了可通過檔案上傳提交的檔案型別,實現了開啟檔案視窗時,預設選中指定的檔案型別:
<input type="file" accept="image/gif"/>
複製程式碼
FileList物件和File物件
在FileList
物件裡的每一個檔案又是一個File
物件
示例:
<form action="" method="post">
<input type="file" id="files" multiple/>
<input type="button" value="顯示檔案" onclick="showFiles()"/>
<p id="msg"></p>
</form>
function ShowFiles(){
// 獲取FileList物件
var fileList = document.getElementById("files").files;
var msg = document.getElementById("msg");
var file;
for(var i=0; i<fileList.length; i++){
file = fileList[i];
msg.innerHTML += file.name + ";<br/>";
}
}
複製程式碼
Blob物件
Blob
物件表示原始二進位制資料,該Blob
介面有兩個屬性:size和type
第一,size屬性,表示Blob物件的位元組長度,可以藉助
FileReader介面讀取Blob物件的二進位制資料,如果Blob物件沒有位元組數,則為0
第二,type屬性,表示Blob物件的MIME
型別,未知 型別,則返回一個 空字串。
第三,slice()方法,使用slice()方法可以實現檔案的切割,並返回一個新的Blob物件。
File物件 和 Blob物件
File物件 繼承了 Blob物件,所以 File物件 也可以使用 Blob物件的屬性和方法(File物件可以使用size屬性 和 type屬性)
獲取檔案的大小和型別
示例:
<form action="" method="post">
<input type="file" id="files" multiple accept="image/*"/>
<input type="button" value="顯示檔案資料" onclick="ShowType()"/>
<p id="msg"></p>
</form>
function ShowType(){
// 獲取FileList物件
var files = document.getElementById("files").files;
var msg = document.getElementById("msg");
var file;
for(var i=0; i<files.length; i++){
file=fileList[i];
msg.innerHTML += "位元組長度:"+file.size+";<br/>";
msg.innerHTML += "檔案型別:"+file.type+";<br/>";
}
}
複製程式碼
FileReader介面卡
FileReader介面 提供了 一些 讀取檔案的方法 與 一個波愛護讀取結果的 事件模型。
FileReader介面 主要把 檔案讀入記憶體, 並讀取檔案中 的資料。
提前檢測瀏覽器是否支援,實現該介面FileReader
if(typeof FileReader == "undefined"){
console.log();
} else {
var reader = new FileReader();
}
複製程式碼
FileReader介面三個屬性:
- 返回讀取檔案的狀態
- 資料
- 讀取時發生的錯誤
readyState屬性,只讀
讀取檔案的狀態:
EMPTYP
,值為0, 表示新的FileReader
介面已經構建,且 沒有呼叫 任何讀取方法 時的預設狀態。LOADING
,值為1,表示有讀取檔案的方法正在讀取 File 物件 或 Blob 物件,且沒有錯誤發生。DONE
,值為2,表示讀取檔案結束,可能整個 File物件 或 Blob物件 已經完全 讀入記憶體 中,在檔案讀取的過程中出現錯誤,或在讀取過程中使用了 abort()方法 強行中斷。
result屬性,只讀
獲取已經讀取的檔案 資料。 如是 圖片,將返回 base64 格式的圖片資料。
error屬性,只讀
獲取讀取檔案過程中出現的錯誤:4種類型
NotFoundError
,找不到讀取的資原始檔。
FileReader介面 會 返回 NotFoundError 錯誤,同時讀取檔案 的方法也會 丟擲 NotFoundError 錯誤異常
SecurityError
,發生安全錯誤。
FileReader 介面 會返回 SecurityError 錯誤,同時讀取檔案的 方法也會丟擲 SecurityError 錯誤異常
NotReadableError
,無法讀取的錯誤。
FileReader 介面會 返回 NotReadableError 錯誤,同時讀取檔案 的方法 也會丟擲 NotReadableError 錯誤異常
EncodingError
,編碼限制的錯誤。
通常是資料的URL
表示的網址 長度受到 限制
FileReader介面的方法
第一,readAsArrayBuffer() 方法,將檔案讀取為 陣列緩衝區
readAsArrayBuffer(<blob>);
複製程式碼
其中的<blob>
表示一個Blob
物件的檔案。
readAsArrayBuffer()方法 會把該 Blob 物件 的檔案讀取為 陣列緩衝區
第二,readAsBinaryString()方法,將檔案讀取為二進位制字串。
readAsBinaryString(<blob>);
複製程式碼
其中的<blob>
表示一個Blob
物件的檔案。
readAsBinaryString()方法 會把該 Blob 物件 的檔案讀取為二進位制字串
第三,readAsText() 方法,將檔案讀取為二進位制字串
readAsText(<blob>,<encoding>);
// 讀取為文字,encoding 為文字的編碼方式
複製程式碼
第四,readAsDataURL()方法 將檔案讀取為 DataURL 字串:
readAsDataURL(<blob>);
// 讀取為DataURL字串
複製程式碼
第五,abort()方法,中斷讀取操作
abort() // 沒有引數
複製程式碼
介面的事件
loadstart
事件,當開始讀取資料時 觸發的事件proress
事件,當正在讀取資料時觸發的事件load
事件,當成功完成資料讀取時觸發的事件abort
事件,當中斷讀取資料時觸發的事件error
事件,當讀取資料發生錯誤時觸發的事件loadend
事件,當結束讀取資料時觸發的事件,資料讀取可能成功也可能失敗
FileReader介面
示例:
// 讀取檔案
function ReadAs(action){
var blob = document.getElementById("files").files[0];
if(blob){
var reader = new FileReader(); // 宣告介面物件
// 讀取檔案的方法
switch(action.toLowerCase()){
case "binarystring":
reader.readAsBinaryString(blob);
break;
case "arraybuffer":
reader.readAsArrayBuffer(blob);
break;
case "text":
reader.readAsText(blob);
break;
case "dataurl":
reader.readAsDataURL(blob);
break;
}
reader.onload = function(e){
// 訪問FileReader 的介面屬性 result,把讀取到記憶體裡的內容獲取出來
var result = this.result;
// 如果是圖檔案
if(/image\/\w+/.test(blob.type) && action.toLowerCase() == "dataurl"){
document.getElementById("result").innerHTML = "<img src='" + result + "'/>";
} else {
document.getElementById("result").innerHTML = result;
}
}
}
}
複製程式碼
FileReader介面的事件
示例:
<form action="" method="post">
<input type="file" id="files" multiple accept="image/*"/>
<input type="button" value="讀取檔案" onclick="FileReaderEvent()"/>
<p id="message"></p>
</form>
var blob = document.getElementById("files").files[0];
var message = document.getElementById("message");
var reader = new FileReader();
// 新增 loadstart 事件
reader.onloadstart = function(e){
}
// 新增 progress 事件
reader.onprogress = function(e){
}
// 新增 load 事件
reader.onload = function(e){
}
// 新增 abort 事件
reader.onabort = function(e){
}
// 新增 error 事件
reader.onerror = function(e){
}
// 新增 loadend 事件
reader.onloadend = function(e){
}
複製程式碼
圖片拖入瀏覽器
示例:
定義一個拖放的 drop 事件處理函式 dropHandle()
定義一個用於載入單個 檔案的函式 loadImg()
// 目標元素的變數
var target;
// drop 事件處理函式
function dropHandle(e){
// 獲取拖拽的檔案
var fileList = e.dataTransfer.files,
fileType;
// 遍歷
for(var i=0; i<fileList.length; i++){
fileType = fileList[i].type;
if(fileType.indexOf('image') == -1) {
alert('');
return;
}
// 載入單個檔案
loadImg(fileList[i]);
}
}
// 載入
function loadImg(file){
// 宣告介面物件
var reader = new FileReader();
// 新增load事件處理
reader.onload = function(e){
var oImg = document.createElement("img");
oImg.src = this.result;
target.appendChild(oImg);
}
// 讀取檔案
reader.readAsDataURL(file);
}
複製程式碼
頁面載入完成後,可獲取target
目標容器,是用於存放拖放進的圖片。
給target
容器新增 dragover
事件處理 和 drop
事件處理
window.onload = function() {
// 獲取目標元素
target = document.getElementById('dropTarget')
// 給目標元素新增 dragover 事件處理
target.addEventListener('dragover', function(e){
e.preventDefault();
},false);
target.addEventListener('drop', dropHandle, false);
}
複製程式碼
❤️關注+點贊+收藏+評論+轉發❤️,原創不易,鼓勵筆者創作更好的文章
點贊、收藏和評論
如果大家想學習前端方面的技術,我把我多年的經驗分享給大家,還有一些學習資料,分享微信:qingqian419