1. 程式人生 > 其它 >HTML5中的拖放功能 | 打卡每天一份勸退技能

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介面

增加的標籤特性

html5file型別的表單元素增加了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介面三個屬性:

  1. 返回讀取檔案的狀態
  2. 資料
  3. 讀取時發生的錯誤

readyState屬性,只讀

讀取檔案的狀態:

  1. EMPTYP,值為0, 表示新的FileReader介面已經構建,且 沒有呼叫 任何讀取方法 時的預設狀態。
  2. LOADING,值為1,表示有讀取檔案的方法正在讀取 File 物件 或 Blob 物件,且沒有錯誤發生。
  3. DONE,值為2,表示讀取檔案結束,可能整個 File物件 或 Blob物件 已經完全 讀入記憶體 中,在檔案讀取的過程中出現錯誤,或在讀取過程中使用了 abort()方法 強行中斷。

result屬性,只讀

獲取已經讀取的檔案 資料。 如是 圖片,將返回 base64 格式的圖片資料。

error屬性,只讀

獲取讀取檔案過程中出現的錯誤:4種類型

  1. NotFoundError,找不到讀取的資原始檔。

FileReader介面 會 返回 NotFoundError 錯誤,同時讀取檔案 的方法也會 丟擲 NotFoundError 錯誤異常

  1. SecurityError,發生安全錯誤。

FileReader 介面 會返回 SecurityError 錯誤,同時讀取檔案的 方法也會丟擲 SecurityError 錯誤異常

  1. NotReadableError,無法讀取的錯誤。

FileReader 介面會 返回 NotReadableError 錯誤,同時讀取檔案 的方法 也會丟擲 NotReadableError 錯誤異常

  1. 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() // 沒有引數
複製程式碼

介面的事件

  1. loadstart事件,當開始讀取資料時 觸發的事件
  2. proress事件,當正在讀取資料時觸發的事件
  3. load事件,當成功完成資料讀取時觸發的事件
  4. abort事件,當中斷讀取資料時觸發的事件
  5. error事件,當讀取資料發生錯誤時觸發的事件
  6. 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