国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

H5拖放異步文件上傳之二——上傳進(jìn)度監(jiān)聽

Godtoy / 694人閱讀

摘要:添加功能顯示待上傳文件列表支持移除待上傳文件使用顯示上傳進(jìn)度支持中斷上傳方法返回一個(gè)對(duì)象,用來表示上傳的進(jìn)度。監(jiān)聽數(shù)據(jù)傳輸進(jìn)行中通過監(jiān)聽這個(gè)事件,可獲得上傳進(jìn)度。

??上一篇《H5拖放+FormData接口+NodeJS,完整異步文件上傳(一)》,我們走通了拖放文件上傳的整個(gè)流程,但離實(shí)際使用場(chǎng)景還有差距。這篇,我們來添加幾個(gè)實(shí)際使用場(chǎng)景必要的功能,向?qū)嶋H使用再走一步。

添加功能

顯示待上傳文件列表;

支持移除待上傳文件;

使用upload.onprogress顯示上傳進(jìn)度;

支持中斷上傳;

upload.progress
XMLHttpRequest.upload方法返回一個(gè) XMLHttpRequestUpload對(duì)象,用來表示上傳的進(jìn)度。這個(gè)對(duì)象是不透明的,但是作為一個(gè)XMLHttpRequestEventTarget,可以通過對(duì)其綁定事件來追蹤它的進(jìn)度。onprogres監(jiān)聽數(shù)據(jù)傳輸進(jìn)行中(通過監(jiān)聽這個(gè)事件,可獲得上傳進(jìn)度)。摘自MDN
實(shí)現(xiàn)思路

??拖放文件到上傳區(qū)域時(shí),將文件保存在一個(gè)文件數(shù)組中,添加并顯示文件相關(guān)信息和移除按鈕,點(diǎn)擊移除按鈕刪除文件數(shù)組中對(duì)應(yīng)的文件元素,點(diǎn)擊上傳按鈕,遍歷文件數(shù)組,開始上傳待上傳文件,此時(shí)點(diǎn)擊移除按鈕則中止文件上傳。

代碼
//相關(guān)樣式
.drop-area{
    margin:auto;
    width: 500px;
    height: 500px;
    border:1px pink dashed;
}
.close-btn{
    cursor: pointer;
}
.close-btn:after{
    float: right;
    content: "X";
    color: red;
}
#fileList{
    width: 95%;
}
.process-bar{
    position: relative;
    margin: 0 10px 0 10px;
    width: 198px;
    height: 18px;
    display: none;
    text-align: center;
    line-height: 20px;
    color: #6dbfff;
    border-radius: 3px;
    border: 1px solid #1483d8;    
    background: #fff;
}
.success .process-bar,
.uploading .process-bar{
    display: inline-block;
}
.process-bar .process-text{
    position: relative;
    z-index: 1;
}
.process-bar .process-rate{
       position: absolute;
    width: 0;
    height: 100%;
       left: 0;
      top: 0;
      border-radius: 3px;
    background: #1483d8;
}
.file-list .success .process-text,
.file-list .success .close-btn:after,
.file-list .error .process-text,
.file-list .error .close-btn:after{
    display: none;
}
 .success .process-bar :after,
.error .process-bar :after{
    content:"success";
    position: absolute;    
    margin: auto;
    left: 0;
    right: 0;
    z-index: 2;
}
.error .process-bar:after{
    content: "error";
    color: red;
}

//Javascript代碼
let filesSet = []; //文件保存數(shù)組
let fileList = document.getElementById("fileList"); //獲取顯示文件列表DOM

/**
 * 創(chuàng)建一個(gè)新的空白的文檔片段frag
 * 用于附加多個(gè)待上傳文件的DOM,可減小回流
 * https://developer.mozilla.org/zh-CN/docs/Web/API/Document/createDocumentFragment
 */
let frag = document.createDocumentFragment();
let barDom = createProccessBar(); //創(chuàng)建進(jìn)度條DOM
let submit = document.getElementById("submit") //獲取提交按鈕


/* 拖動(dòng)到放置區(qū)域時(shí) */
function dragover_hander (event) {
    /* 必須同時(shí)阻止dragover和drop的默認(rèn)事件
       否則會(huì)響應(yīng)瀏覽器默認(rèn)行為
       瀏覽器器能顯示的文件會(huì)直接顯示,例如html文件、圖片文件
       瀏覽器器不能顯示的文件會(huì)出現(xiàn)文件下載彈窗
    */
    event.preventDefault(); 
}

/*拖放完成事件*/
function drop_hander (event) {

    event.preventDefault(); //阻止默認(rèn)事件

    var files = event.dataTransfer.files; //通過dataTransfer對(duì)象獲取文件對(duì)象數(shù)組

    for(let file of files) { //遍歷文件對(duì)象數(shù)組

       //創(chuàng)建文件信息顯示DOM,并保存在file對(duì)象的element屬性中,用于后續(xù)操作
       file.element = createFileDom(file, filesSet.length)
       //復(fù)制進(jìn)度條DOM,并保存在file對(duì)象的processBar屬性中,用于后續(xù)操作
       file.processBar = filesSet.length?barDom.cloneNode(true):barDom;
       //將進(jìn)度條添加至文件信息顯示DOM中
       file.element.appendChild(file.processBar);
       //file文件對(duì)象添加到文件保存數(shù)組
       filesSet.push(file);
       //創(chuàng)建文件信息顯示DOM添加至文檔片段frag
       frag.appendChild(file.element);
    }

    //將文件列表添加至顯示文件列表的div
    fileList.appendChild(frag)
}


/**
 * 創(chuàng)建文件信息顯示DOM
 * file  文件對(duì)象,用于獲取文件信息
 * index 文件對(duì)象在數(shù)組中的索引,用于刪除
 */
function createFileDom (file, index) {
    let p = document.createElement("p"); 
    //file.name屬性可以獲得文件名稱
    //有興趣的童鞋,可以使用for...in循環(huán)查看一下file對(duì)象的其它屬性值
    let text = document.createTextNode(file.name); 
    let span = document.createElement("span");
    span.setAttribute("index", index); //索引添加至按鈕的index屬性
    span.className = "close-btn"; 
    p.appendChild(text);
    p.appendChild(span);

    return p; //返回文件信息顯示DOM
}
/**
 * 創(chuàng)建進(jìn)度條DOM,
 * 進(jìn)度條DOM結(jié)構(gòu)固定,可使用clone(true)進(jìn)行復(fù)制
 * @return {[type]} [description]
 */
function createProccessBar() {
    let bar =  document.createElement("span");
    let rate = document.createElement("span");
    let text = document.createElement("span");
    bar.className = "process-bar";
    rate.className = "process-rate";
    text.className = "process-text";
    text.innerText="0%";
    bar.appendChild(text);
    bar.appendChild(rate);
    return bar; 
} 

//通過事件代理,監(jiān)聽移除或中止上傳
fileList.addEventListener("click", (evt)=>{
    let index = evt.target.getAttribute("index"); //獲得index屬性值
    if (index) { //存在index屬性值,表示點(diǎn)擊了刪除按鈕

        if (filesSet[index].unloading && filesSet[index].req) { //文件已經(jīng)上傳中
            filesSet[index].req.abort(); //中止上傳
            filesSet[index].unloading = false;    //將上傳中的狀態(tài)設(shè)置為false    
        } else { //未開始上傳
            filesSet[index].element.remove(); //移除DOM
            filesSet[index].element = null; //釋放對(duì)DOM的引用
            filesSet[index].processBar = null;//釋放對(duì)DOM的引用
            delete filesSet[index];//刪除文件數(shù)組中對(duì)應(yīng)的元素    
        }

    }
})

submit.addEventListener("click",function(){// 為上傳按鈕綁定事件

    //這里使用for...in循環(huán),正好可以避免對(duì)數(shù)組稀疏元素的遍歷
    for(let key in filesSet){
        //如果正在上傳中或已經(jīng)上傳完成,不再上傳
        if (filesSet[key].unloading || filesSet[key].uploaded) continue; 
        filesSet[key].unloading = true; //標(biāo)記開始上傳

        //創(chuàng)建一個(gè)文件上傳的Promise,并設(shè)置成功及失敗的回調(diào)
        initUpload(filesSet[key]).then(file => {
            //上傳成功
            file.element.className = "success"; //UI顯示成功信息
            file.uploaded = true; //標(biāo)記上傳成功
        }).catch((file, err) => {
            file.element.className = "error"; //UI顯示失敗信息
            //取消開始上傳標(biāo)記,點(diǎn)擊上傳按鈕將嘗試再次上傳
            filesSet[key].unloading = false; 
        })
    }
})

/**
 * 返回一個(gè)文件上傳的Promise實(shí)例
 * @param  {[type]} file 要上傳的文件
 */
function initUpload(file){

    return new Promise((res, rej) => {
        let formData = new FormData();//聲明一個(gè)FormData實(shí)例
        let req = new XMLHttpRequest();//創(chuàng)建XHR實(shí)例
        let reta = file.processBar.querySelector(".process-rate");//獲得進(jìn)度條DOM
        let text = file.processBar.querySelector(".process-text");//獲得進(jìn)度文本DOM
        let pre;//保存上傳百分比
        //監(jiān)聽數(shù)據(jù)傳輸進(jìn)行中
        req.upload.onprogress =function(data){ 
            pre = (data.loaded/data.total*100).toFixed(2);//計(jì)算百分比
            reta.style.width = pre +"%";//修改進(jìn)度條
            text.innerText = pre +"%" ;//修改進(jìn)度條文本
        }
        //監(jiān)聽請(qǐng)求完成
        req.onreadystatechange = function () {
            if (req.readyState !==4 ) return ; 
            if (req.status === 200 ){
                //完成,執(zhí)行成功回調(diào)
                res(file, req)
            } else {
                //失敗,執(zhí)行失敗回調(diào)
                rej(file, req)
            }
        }
        formData.append("file",file); //使用append方法添加文件到file鍵
        req.open("POST", "/process_post"); //初始化請(qǐng)求
        req.send(formData); //發(fā)送請(qǐng)求
        file.req = req; //保存req對(duì)象,用于中止請(qǐng)求
        //形如顯示上傳進(jìn)度
        file.element.className = "uploading"                
    })
}

??到這里代碼就結(jié)束了,完整代碼可以查看Github。因?yàn)槭潜镜厣蟼鳎跍y(cè)試的時(shí)候可以使用大一些的文件,或者限制一下上傳。

結(jié)束語(yǔ)

??這些新的API,使得文件拖放上傳變得簡(jiǎn)單起來。可惜低版本的IE并不支持,聽說低版本的IE可以使用Falsh來進(jìn)行文件上傳,具體是如何實(shí)現(xiàn)的,要不我們下篇再來探討一下。
??
??

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/94265.html

相關(guān)文章

  • H5拖放異步文件上傳之二——上傳進(jìn)度監(jiān)聽

    摘要:添加功能顯示待上傳文件列表支持移除待上傳文件使用顯示上傳進(jìn)度支持中斷上傳方法返回一個(gè)對(duì)象,用來表示上傳的進(jìn)度。監(jiān)聽數(shù)據(jù)傳輸進(jìn)行中通過監(jiān)聽這個(gè)事件,可獲得上傳進(jìn)度。 ??上一篇《H5拖放+FormData接口+NodeJS,完整異步文件上傳(一)》,我們走通了拖放文件上傳的整個(gè)流程,但離實(shí)際使用場(chǎng)景還有差距。這篇,我們來添加幾個(gè)實(shí)際使用場(chǎng)景必要的功能,向?qū)嶋H使用再走一步。 添加功能 顯...

    blankyao 評(píng)論0 收藏0
  • H5拖放+FormData接口+NodeJS,完整異步文件上傳(一)

    摘要:前段時(shí)間面試過程中,頻繁遇到異步文件上傳的相關(guān)問題。所以,這會(huì)是一個(gè)拖放接口實(shí)現(xiàn)文件異步上傳的完整。監(jiān)聽放置元素的事件,通過對(duì)象可以獲得拖拽事件的狀態(tài)及數(shù)據(jù)。后端文件接收保存后端使用實(shí)現(xiàn)文件上傳。 ??前段時(shí)間面試過程中,頻繁遇到H5異步文件上傳的相關(guān)問題。還遇到過一個(gè)通過H5拖放功能實(shí)現(xiàn)文件異步上傳的問題,大概知道H5有新增拖拽功能可以接收文件,如何異步上傳文件就母雞了(攤手)。面試...

    NervosNetwork 評(píng)論0 收藏0
  • 圖片上傳知識(shí)點(diǎn)梳理

    摘要:在日常項(xiàng)目開發(fā)中,圖片上傳是一個(gè)十分常見的場(chǎng)景。在圖片拖拽上傳這個(gè)業(yè)務(wù)場(chǎng)景中,被拖拽元素為頁(yè)面外部的圖片文件,故此處僅用到目標(biāo)元素的各個(gè)事件。具體實(shí)現(xiàn)代碼如下至此,圖片上傳的常用知識(shí)點(diǎn)以梳理完畢,歡迎補(bǔ)充。 在日常項(xiàng)目開發(fā)中,圖片上傳是一個(gè)十分常見的場(chǎng)景。而現(xiàn)在的各種UI框架都提供了自己的上傳組件,網(wǎng)上第三方的上傳組件也多如牛毛。可能你早已習(xí)慣了直接使用這些現(xiàn)成的組件,然而對(duì)于其具體的...

    Pink 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<