文件API
FileList對象與file對象
FileList
對象表示用戶選擇的文件列表扇雕。在HTML4中吓肋,file
控件內(nèi)只允許放置一個文件签孔, 但是到了H5中地熄,通過添加multiple
屬性华临,file
控件內(nèi)允許一次放置多個文件《丝迹控件內(nèi)的每一個用戶選擇的文件都是一個file
對象雅潭,而FileList
對象則為這些file
對象的列表,代表用戶選擇的所有文件却特。file
對象有兩個屬性寻馏,name
屬性表示文件名, 不包括路徑核偿,lastModifiedDate
屬性表示文件的最后修改日期诚欠。
<script language=javascript>
function ShowFileName(){
var file;
//document.getElementById("file").files返回FileList文件列表對象
for(var i=0;i<document.getElementById("file").files.length;i++){
//file對象為用戶選擇的單個文件
file = document.getElementById("file").files[i];
//此處您可以針對FileList文件列表中每個文件進行多種處理,本例中只彈出文件名
alert(file.name);
}
}
</script>
選擇文件:
<input type="file" id="file" multiple size="80"/>
<input type="button" onclick="ShowFileName();" value="文件上傳"/>
Blob對象
Blob
表示二進制原始數(shù)據(jù)漾岳,它提供一個slice
方法轰绵,可以通過該方法訪問到字節(jié)內(nèi)部的原始數(shù)據(jù)塊。事實上尼荆,上面提到的file
對象也繼承了這個Blob
對象.
Blob
對象有兩個屬性左腔,size
屬性表示一個Blob
對象的字節(jié)長度掉缺。type
屬性表示Blob
的MIME類型攘须,如果是未知類型,則返回一個空字符串岖赋。
function ShowFileType(){
var file;
//得到用戶選擇的第一個文件
file = document.getElementById("file").files[0];
var size=document.getElementById("size");
//顯示文件字節(jié)長度
size.innerHTML=file.size;
var type=document.getElementById("type");
//顯示文件類型
type.innerHTML=file.type;
}
</script>
選擇文件:
<input type="file" id="file" />
<input type="button" value="顯示文件信息" onclick="ShowFileType();"/><br/>
文件字節(jié)長度:<span id="size"></span><br/>
文件類型:<span id="type"></span>
對于圖像類型的文件巧还,Blob
對象的type
屬性都是以image/
開頭的鞭莽,后跟圖像類型,利用此特性我們可以在JS中判斷用戶選擇的文件是否為圖像文件麸祷,如果在批量上傳時澎怒,只允許上傳圖像文件,可以利用該屬性阶牍,如果用戶選擇的多個文件中有不是圖像的文件時喷面,可以彈出錯誤提示信息星瘾,并停止后面的文件上傳,或者跳過這個文件惧辈,不將該文件上傳琳状。
function FileUpload(){
var file;
for(var i=0;i<document.getElementById("file").files.length;i++){
file = document.getElementById("file").files[i];
if(!/image\/\w+/.test(file.type)){
alert(file.name+"不是圖像文件!");
break;
}
else{
//此處可加入文件上傳的代碼
alert(file.name+"文件已上傳");
}
}
}
</script>
選擇文件:
<input type="file" id="file" multiple/>
<input type="button" value="文件上傳" onclick="FileUpload();"/>
另外盒齿,H5中已經(jīng)對file
控件添加了accept
屬性念逞,企圖讓file
控件只能接受某種類型的文件,但是目前各主流瀏覽器對其的支持都只限于在打開文件選擇窗口時县昂,默認選擇圖像文件而己肮柜,如果選擇其他類型文件陷舅,file
控件也能正常接受倒彰。
<input type="file" id="file" accept="image/*" />
FileReader接口
FileReader
接口主要用來把文件讀入內(nèi)存,并且讀取文件中的數(shù)據(jù)莱睁。FileReader
接口提供 了一個異步API 待讳,使用該API可以在瀏覽器主線程中異步訪問文件系統(tǒng),讀取文件中的數(shù)據(jù)仰剿。
//檢測瀏覽器是否支持FileReader接口
if(typeof FileReader=='undefined'){
alert("瀏覽器不支持FileReader接口")
}else{
var reader=new FileReader();
}
FileReader接口的方法
FileReader
接口擁有4個方法创淡,其中3個用以讀取文件,另一個用來將讀取過程中斷南吮。無論讀取成功或失敗琳彩,方住并不會返回讀取結(jié)果,這一結(jié)果存儲在result
屬性中部凑。
readAsText
方法第二個參數(shù)是文本的編碼方式露乏,默認值為UTF-8。readAsBinaryString
這個方法將文件讀取為二進制字符串涂邀,通常我們將它傳送到后端瘟仿,后端可以通過這段字符串存儲文件。readAsDataURL
方法將文件讀取為一串Data URL字符串比勉,該方法事實上是將小文件以一種特殊格式的URL地址形式直接讀入頁面劳较。這里的小文件通常是指圖像與html
等格式的文件。
FileReader接口的事件
FileReader
接口還包含了一套完整的事件模型浩聋,用于捕獲讀取文件時的狀態(tài)观蜗。
FileReader接口的使用示例
<script language=javascript>
var result=document.getElementById("result");
var file=document.getElementById("file");
if (typeof FileReader == 'undefined' ){
result.innerHTML = "<p>抱歉,你的瀏覽器不支持 FileReader</p>";
file.setAttribute( 'disabled','disabled' );
}
//將文件以Data URL形式進行讀入頁面
function readAsDataURL(){
//檢查是否為圖像文件
var file = document.getElementById("file").files[0];
if(!/image\/\w+/.test(file.type)){
alert("請確保文件為圖像類型");
return false;
}
var reader = new FileReader();
//將文件以Data URL形式進行讀入頁面
reader.readAsDataURL(file);
reader.onload = function(e){
var result=document.getElementById("result");
//在頁面上顯示文件
result.innerHTML = '![]('+this.result+')'
}
}
//將文件以二進制形式進行讀入頁面
function readAsBinaryString(){
var file = document.getElementById("file").files[0];
var reader = new FileReader();
//將文件以二進制形式進行讀入頁面
reader.readAsBinaryString(file);
reader.onload = function(f){
var result=document.getElementById("result");
//在頁面上顯示二進制數(shù)據(jù)
result.innerHTML=this.result;
}
}
//將文件以文本形式進行讀入頁面
function readAsText(){
var file = document.getElementById("file").files[0];
var reader = new FileReader();
//將文件以文本形式進行讀入頁面
reader.readAsText(file);
reader.onload = function(f){
var result=document.getElementById("result");
//在頁面上顯示讀入文本
result.innerHTML=this.result;
}
}
</script>
<p>
<label>請選擇一個文件:</label>
<input type="file" id="file" />
<input type="button" value="讀取圖像" onclick="readAsDataURL()"/>
<input type="button" value="讀取二進制數(shù)據(jù)" onclick="readAsBinaryString()"/>
<input type="button" value="讀取文本文件" onclick="readAsText()"/>
</p>
<div name="result" id="result">
<!-- 這里用來顯示讀取結(jié)果 -->
</div>
在這個示例中衣洁,選取不同類型的文件嫂便,然后點擊不同的按鈕,瀏覽器會讀取這些文件的各種數(shù)據(jù)闸与,然后顯示在畫面中毙替。當(dāng)然您也可以選擇不顯示 岸售,而是直接提交到后端,然后保存到文件中或輸送到數(shù)據(jù)庫中厂画。代碼中fileReader
對象讀取到的數(shù)據(jù)都保存在了result
屬性中凸丸。
<script language=javascript>
var result=document.getElementById("result");
var input=document.getElementById("input");
if(typeof FileReader=='undefined'){
result.innerHTML = "<p class='warn'>抱歉,你的瀏覽器不支持 FileReader</p>";
input.setAttribute( 'disabled','disabled' );
}
function readFile(){
var file = document.getElementById("file").files[0];
var reader = new FileReader();
reader.onload = function(e){
result.innerHTML = '![]('+this.result+')'
alert("load");
}
reader.onprogress = function(e){
alert("progress");
}
reader.onabort = function(e){
alert("abort");
}
reader.onerror = function(e){
alert("error");
}
reader.onloadstart = function(e){
alert("loadstart");
}
reader.onloadend = function(e){
alert("loadend");
}
reader.readAsDataURL(file);
}
</script>
<p>
<label>請選擇一個圖像文件:</label>
<input type="file" id="file" />
<input type="button" value="顯示圖像" onclick="readFile()" />
</p>
<div name="result" id="result">
<!-- 這里用來顯示讀取結(jié)果 -->
</div>
在這個示例中袱院,我們通過點擊顯示圖像按鈕在畫面中讀入一個圖像文件屎慢,通過這個過程我們可以了解按順序觸發(fā)了哪些事件,并用提示信息的形式報出這些事件的名字忽洛。我們需要編寫的代碼主要都是在onprogress
事件中腻惠,譬如可以用H5中的新增元素progress
來顯示大文件的讀取完成百分比。
拖放
拖放步驟
1.將想要拖放的對象元素的draggable
屬性設(shè)為true
欲虚,這樣才能將該元素進行拖放集灌。另外,img
元素與a
元素(必須指定href
)默認允許拖放复哆。
2.編寫與拖放有關(guān)的事件處理代碼欣喧。
示例:
<title>拖放示例</title>
<script type="text/javascript">
function init() {
var source = document.getElementById("dragme");
var dest = document.getElementById("text");
// (1) 拖放開始
source.addEventListener("dragstart", function(ev) {
// 向dataTransfer對象追加數(shù)據(jù)
var dt = ev.dataTransfer;
dt.effectAllowed = 'all';
//(2) 拖動元素為dt.setData("text/plain", this.id);
dt.setData("text/plain", "你好");
}, false);
// (3) dragend:拖放結(jié)束
dest.addEventListener("dragend", function(ev) {
//不執(zhí)行默認處理(拒絕被拖放)
ev.preventDefault();
}, false);
// (4) drop:被拖放
dest.addEventListener("drop", function(ev) {
// 從DataTransfer對象那里取得數(shù)據(jù)
var dt = ev.dataTransfer;
var text = dt.getData("text/plain");
dest.textContent += text;
//(5) 不執(zhí)行默認處理(拒絕被拖放)
ev.preventDefault();
//停止事件傳播
ev.stopPropagation();
}, false);
}
//(6) 設(shè)置頁面屬性,不執(zhí)行默認處理(拒絕被拖放)
document.ondragover = function(e){e.preventDefault();};
document.ondrop = function(e){e.preventDefault();};
</script>
<body onload="init()">
<h1>簡單拖放示例</h1>
<!-- (7) 把draggable屬性設(shè)為true -->
<div id="dragme" draggable="true" style="width: 200px; border: 1px solid gray;">
請拖放
</div>
<div id="text" style="width: 200px; height: 200px; border: 1px solid gray;"></div>
</body>
代碼解釋:
- 開始拖動(
dragstart
)時梯找,把要拖動的數(shù)據(jù)存入DataTransfer
對象(setData()
方法)唆阿。DataTransfer
對象專門用來存放拖放時要攜帶的數(shù)據(jù),它可以被設(shè)置為拖動事件對象的dataTransfer
屬性锈锤。setData
方法中的第一個參數(shù)為攜帶數(shù)據(jù)的數(shù)據(jù)種類的字符串驯鳖,第二個參數(shù)為要攜帶的數(shù)據(jù)。第一個參數(shù)中表示數(shù)據(jù)種類的字符串里只能填入類似text/plain
或text/html
的表示MIME類型的文字久免,不能填入其它文字浅辙。 - 如果把
dt.setData("text/plain","你好");
改為dt.setData("text/plain",this.id);
,因為把被拖動元素的id
當(dāng)成了參數(shù)妄壶,所以攜帶的數(shù)據(jù)就是被拖動元素中的數(shù)據(jù)了摔握,因為瀏覽器在使用getData方法讀取數(shù)據(jù)時會自動讀取該元素中的數(shù)據(jù)。 - 針對拖放的目標元素丁寄,必須在
dragend
或dragover
事件內(nèi)調(diào)用事件對象.preventDefault()
方法氨淌。因為默認情況下,拖放的目標元素是不允許接收元素的伊磺,為了把元素拖放到其中盛正,必須把默認處理關(guān)閉掉。 - 目標元素接受到被拖放的元素后屑埋,執(zhí)行
getData()
方能從DataTransfer
那里獲得數(shù)據(jù)豪筝。getData()
方法的參數(shù)為setData()
方法中指定的數(shù)據(jù)種類。 - 要實現(xiàn)拖放過程,必須在目標元素的
drop
事件中關(guān)閉默認處理(拒絕被拖放)续崖,還必須設(shè)定整個頁面為不執(zhí)行默認處理(拒絕被拖放)敲街,否則目標元素不能接受被拖放的元素。 - 要使元素可以被拖放严望,首先必須把該元素的
draggable
屬性設(shè)為true
多艇。另外,為了讓這個示例在所有支持拖放API的瀏覽器中都能正常運行像吻,需要指定-webkit-user-drag:element
這種Webkit特有的屬性峻黍。 - 因為這個示例中的數(shù)據(jù)種類使用了
text/plain
這個MIME類型,也可以從其他使用同樣MIME類型的應(yīng)用程序中把該類型的數(shù)據(jù)拖動到目標元素中拨匆。
支持拖動處理的MIME的類型為:
-
text/plain
:文本文字 -
text/html
:HTML文字 -
text/xml
:XML文字 -
text/uri-list
:URL列表姆涩,每個URL為一行
DataTransfer對象的屬性與萬法
如果DataTransfer
對象的屬性和方能使用得好,可以實現(xiàn)定制拖放圖標惭每,讓它只支持特定拖放(如拷貝/移動) 等骨饿,甚至可以實現(xiàn)更復(fù)雜的拖放操作。
屬性/方法 | 描述 |
---|---|
dropEffect屬性 | 表示拖放操作的視覺效果洪鸭,允許對其進行值的設(shè)定样刷。該效果必須在用effectAllowed屬性指定的允許的視覺效果的范圍內(nèi)仑扑,允許指定的值為none览爵、copy、link镇饮、move |
effectAllowed屬性 | 用來指定當(dāng)前元素能被拖放時所允許的視覺效果蜓竹。可以指定的值為none储藐、copy俱济、copyLink、copyMove钙勃、link蛛碌、linkMove、move辖源、all蔚携、unintialize |
types屬性 | 存入數(shù)據(jù)的種類,字符串的偽數(shù)組 |
void clearDaata(DOMString format)方法 | 消除DataTransfer對象中存放的數(shù)據(jù)克饶。如果省略參數(shù)format酝蜒,則消除全部數(shù)據(jù) |
void setData(DOMString format、DOMString data) | 向DataTransfer對象內(nèi)存入數(shù)據(jù) |
DOMString getData(DOMString format) | 從DataTransfer對象中讀數(shù)據(jù) |
void setDragImage(Element image,long x,long y) | 用img元素來設(shè)置拖放圖標(部分瀏覽器可用canvas等其他元素) |
setData
方法在拖放開始時向dataTransfer
對象中存入數(shù)據(jù)矾湃,它用types
屬性來指定數(shù)據(jù)的MIME類型亡脑。getData
方法在拖動結(jié)束時讀取dataTransfer
對象中的數(shù)據(jù)。clearData
方法可以用來清除DataTransfer
對象內(nèi)的數(shù)據(jù)。
設(shè)定拖放時的視覺效果
dropEffect
屬性與effectAllowed
屬性結(jié)合起來可以設(shè)定拖放時的視覺效果霉咨。effectAllowed
屬性表示當(dāng)一個元素被拖動時所允許的視覺效果蛙紫,一般在ondragstart
事件中設(shè)定,允許設(shè)定的值為none途戒、copy惊来、copyLink、copyMove棺滞、link裁蚁、linkMove、move继准、all枉证、unintialize
。dropEffect
屬性表示實際拖放時的視覺效果移必, 一般在ondragover
事件中指定室谚,允許設(shè)定的值為none、copy崔泵、link秒赤、move
。dropEffect
屬性所表示的實際視覺數(shù)果必須在effectAllowed
屬性所表示的允許的視覺效果范圍內(nèi)憎瘸。規(guī)則如所示入篮。
- 如果
effectAllowed
屬性設(shè)定為none
,則不允許拖放元素 - 如果
dropEffect
屬性設(shè)定為none
幌甘,則不允許被拖放到目標元素中 - 如果
effectAllowed
屬性設(shè)定為all
或不設(shè)定潮售,則dropEffect
屬性允許被設(shè)定為任何值,并且按指定的視覺效果進行顯示 - 如果
effectAllowed
屬性設(shè)定為具體效果(不為none锅风、all
) 酥诽,dropEffect
屬性也設(shè)定了具體視覺效果,則兩個具體效果值必須完全相等皱埠,否則不允許將被拖放元素拖放到目標元素中
source.addEventListener( "dragstart" , function(ev){
var dt = ev.dataTransfer;
//設(shè)定effectAllowed屬性
dt.effectAllowed ='copy';
dt.setData("text/plain","你好") ;
}, false);
dest.addEventListener( "dragover" , function (ev){
var dt = ev.dataTransfer;
//設(shè)定dropEffect屬性
dt.dropEffect ='copy';
ev.preventDefault();
}, false);
自定義拖放圖標
H5中允許自定義拖放圖標——指的是在用鼠標拖動元素的過程中肮帐,位于鼠標指針下部的小圖標。
DataTransfer
對象有一個setDragImage
方法边器,該方法有三個參數(shù)训枢,第一個參數(shù)image
設(shè)定為拖放圖標的圖標元素,第二個參數(shù)x
為拖放圖標離鼠標指針的x
軸方向的位移量饰抒,第三個參數(shù)y
為拖放圖標離鼠標指針的y
軸方向的位移量肮砾。
//創(chuàng)建圖標元素
var dragIcon = document.createElement('img');
//設(shè)定圖標來源
dragIcon.src = 'http://twivatar.orq/twitter/mini';
source.addEventListener("dragstart", function(ev) {
var dt = ev.dataTransfer;
//設(shè)定自定義圖標
dt.setDragImage(dragIcon, -10, -10);
dt.setData("text/plain","aaa");
}, false);