• js 文件异步上传 显示进度条 显示上传速度 预览文件


    通常文件异步提交有几个关键

    1.支持拖拽放入文件。2.限制文件格式。3.预览图片文件。4.上传进度,速度等,上传途中取消上传。5.数据与文件同时上传

    现在开始笔记:

    需要一个最基础的元素<input id="inputFile" type=file multiple="multiple">

    一、首先我们需要实现最基本的异步上传功能

    //获得input元素的文件

    var fileObj = document.getElementById("inputFile").files;

    //定义一个表单数据对象

    var form = new FormData();

    //将文件input的文件信息放入表单数据对象中

    for(var i in fileObj)
    {
            form.append("file[]", fileObj[i]); // 文件对象
     }

    //定义一个xhr对象

    var xhr = new XMLHttpRequest() || new ActiveXObject("Microsoft.XMLHTTP");

    //创建一个http请求

     xhr.open("post",url,true);

    //发送数据

    xhr.send(form);

    这样数据就上传成功了。

    二、接下来说明如何捕获文件上传开始,过程中,结束的各种信息状态

    主要是几个xhr回调函数

    xhr.onload = function(evt){};//上传请求完成

    xhr.onerror = function(evt){};//上传异常

    xhr.upload.onloadstart = function(evt){};//开始上传

    xhr.upload.onprogress =function(evt){};//上传进度  这个方法会在文件每上传一定字节时调用

    evt.loaded//表示已经上传了多少byte的文件大小

    evt.total//表示文件总大小为多少byte

    通过这两个关键的属性就可以去计算 上传进度与速度

    xhr.onreadystatechange = function(){}//当xhr的状态(上传开始,结束,失败)变化时会调用

    该方法可以用来在文件上传完成后接收服务器返回的内容  xhr.responceText

    中途取消上传 xhr.abort();

    三、关于限制文件格式

    在fileObj[i]中有个type属性可以使用

    四、传文件的时候需要传其他数据

    只需要

    form.append("name","potatog");

    这种键值录入即可。

    只是需要注意后台获取数据是 不是在$_FILE中。

    五、文件拖放

    定义一个用来接收拖放事件的元素

    如:

    <div id="holder" style="150px;height:150px;border:5px solid red;"></div>

         //检查浏览器是否支持拖放上传。
      if('draggable' in document.createElement('span')){
        var holder = document.getElementById('holder');
        //当拖放的文件悬浮在该元素上方是触发
        holder.ondragover = function () { this.className = 'hover'; return false; };
        //当拖放的文件不再悬浮在该文件上方时调用
        holder.ondragend = function () { this.className = ''; return false; };
        //当拖放的文件放到该元素中时
        holder.ondrop = function (event) {

          event.preventDefault();

          this.className = '';

          //得到拖放的文件  
          var files = event.dataTransfer.files;

         //将文件放入输入框对象的files中
                fileObj.files = files;
                fileObj.onchange();
          return false;
        };

      }

    六、预览图片

    fileObj.onchange = function(){
                  // 检查是否支持FileReader对象
          if (typeof FileReader != 'undefined') {

    //能预览的文件
            var acceptedTypes = {
              'image/png': true,
              'image/jpeg': true,
              'image/gif': true
            };
    得到input=file元素中的所有文件信息
            for(var i = 0; i < fileObj.files.length; i++)
            {

    //如果是支持预览的图片文件
            if (acceptedTypes[fileObj.files[i].type] === true) {
    //新建一个预览对象
              var reader = new FileReader();
    //绑定事件 当数据加载后执行  每有一张图片载入完成就会别调用。
              reader.onload = function (event) {
    //定义一个图片对象
                var image = new Image();
    //将对象载入的结果返回到图片元用来显示
                image.src = event.target.result;

                image.width = 100;

                holder.appendChild(image);

              };


                //开始加载数据 文件
            reader.readAsDataURL(fileObj.files[i]);
            }


            }

          }
        }

    关于异步上传的封装demo代码

    /* pUploadFile.js
     * 使用方法
     * 定义文件异步上传对象
     * var uploadFile = pUploadFile({
                "elId" : "file",
                "previewId" : "show"
            });
     * 定义时必须传递input[type=file]元素的id,
     * preview为选填项  用来预览图片文件的div,即图片文件会以img元素的形式放入preview中
     * 开始上传
     *
     * uploadFile.upload({
     *     
     * });
     *
     *
     * 定义或者执行上传是必须其中一着需要传递参数
     * url 请求地址
     * callback 回调函数名
     *
     */

    (function(){
        window.pUploadFile = function(config)
        {
            return new PotatogUploadFile(config);
        }
        
        function PotatogUploadFile(config)
        {
            //文件input元素id
            this.elId = null;
            //input元素对象
            this.elObj = null;
            
            this.progressBoxWidth = 0;
            
            //请求地址
            this.url = null;
            //上传成功后的回调
            this.success = null;
            //上传失败后的回调
            this.faild = null;
            
            //遮罩盒子
            this.progressBox = null;
            
            //百分比
            this.percent = 0;
            
            this.progressStreak = null;
            
            this.xhr = new XMLHttpRequest() || new ActiveXObject("Microsoft.XMLHTTP");
            
            this.startTime = 0;
            
            this.preTime = 0;
            
            this.preLoad = 0;
            
            this.count = 10;
            
            this.previewId = null;
            this.previewObj = null;
            
            this.data = null;
            
            if(typeof config["previewId"] != "undefined")
            {
                this.previewId = config["previewId"];
                this.previewObj = document.querySelector("#previewId");
            }
            
            if(typeof config["elId"] == "undefined")
            {
                console.error("元素ID缺失");
                return this;
            }
            else
            {
                this.elId = config["elId"];
                this.elObj = document.querySelector("#" + this.elId);
                this.inintDom();
            }
            
            this.url = (typeof config.url == "undefined") ? null : config.url;
            this.callback = (typeof config.callback == "undefined") ? null : config.callback;
            this.method = (typeof config.method == "undefined") ? "post" : config.method;
            this.async = (typeof config.async == "undefined") ? true : config.async;
            
        }
        
        //初始化一些交互元素
        PotatogUploadFile.prototype.inintDom = function(){
            var _this = this;
            var inputWidth = this.progressBoxWidth = parseFloat(getComputedStyle(this.elObj).getPropertyValue("width"));
            var inputHeight = parseFloat(getComputedStyle(this.elObj).getPropertyValue("height"));
            
            var inputX = this.elObj.offsetLeft;
            var inputY = this.elObj.offsetTop;
            console.log(inputX,inputY);
            
            //创建一个元素 用来覆盖住input元素
            var progressBox = document.createElement("div");
            progressBox.style.display = "none";
            progressBox.style.position = "absolute";
            progressBox.style.zIndex = "999";
            progressBox.style.left = inputX + "px";
            progressBox.style.top = inputY + "px";
            
            progressBox.style.width = inputWidth + "px";
            progressBox.style.height = inputHeight + "px";
            
            progressBox.style.background = "rgba(58,147,255,0.1)";
            progressBox.style.border = "1px solid rgba(58,147,255,0.3)";
            
            this.progressBox = progressBox;
            this.elObj.parentNode.appendChild(progressBox);
            
            //进度条
            var progressStreak = document.createElement("div");
            progressStreak.style.height = this.progressBox.style.height;
            
            progressStreak.style.background = "rgba(58,147,255,0.2)";
            
            this.progressStreak = progressStreak;
            this.progressBox.appendChild(progressStreak);
            
            //进度条中间的 百分比文字
            var label = document.createElement("label");
            
            label.style.position = "absolute";
            label.style.top = "0px";
            label.style.right = "5px";
            label.style.lineHeight = this.progressBox.style.height;
            label.style.color = "#3B97FF";
            label.style.fontSize = "10px";
            
            this.label = label;
            this.progressBox.appendChild(label);
            
            //右上角的上传速度 剩余时间预计
            var speed = document.createElement("span");
            
            
            speed.style.position = "absolute";
            speed.style.right = "0px";
            speed.style.top = "-12px";
            
            
            speed.style.color = "rgba(58,147,255,0.6)";
            speed.style.fontSize = "10px";
            
            this.speed = speed;
            this.progressBox.appendChild(speed);
            
            var predict = document.createElement("span");
            predict.style.position = "absolute";
            predict.style.left = "0px";
            predict.style.top = "-12px";
            
            predict.style.color = "rgba(58,147,255,0.6)";
            predict.style.fontSize = "10px";
            
            this.predict = predict;
            this.progressBox.appendChild(predict);
            
            
            //取消上传按钮
            var cancel = document.createElement("span");
            cancel.innerHTML = "×";
            cancel.style.position = "absolute";
            
            cancel.style.top = "-5px";
            cancel.style.right = "1px";
            
            cancel.style.color = "#999";
            cancel.style.cursor = "pointer";
            cancel.onclick = function(){
                _this.progressBox.style.display = "none";
                _this.xhr.abort();
            }
            
            this.cancel = cancel;
            this.progressBox.appendChild(cancel);
        }
        
        
        PotatogUploadFile.prototype.setProgressValue = function(percent)
        {
            this.percent = percent;
            this.progressStreak.style.width = Math.ceil(this.progressBoxWidth * percent) + "px";
            this.label.innerHTML = Math.round(this.percent * 100) + "%";
        }
        
        PotatogUploadFile.prototype.setSpeed = function(value)
        {
            if(value > 1000)value = Math.round(value / 1000 / 1024) +  "M/s";
            else value = value + "K/s"
            this.speed.innerHTML = value;
        }
        
        PotatogUploadFile.prototype.setPredict = function(value)
        {
            var m = parseInt(value / 60);
            var s = value % 60;
            this.predict.innerHTML = "预计剩余:" + m + "分 " + s + "秒";
        }
        
        PotatogUploadFile.prototype.upload = function(config)
        {
            if(this.elObj.value == '')return false;
            this.url = (typeof config.url == "undefined") ? null : config.url;
            this.callback = (typeof config.callback == "undefined") ? null : config.callback;
            this.method = (typeof config.method == "undefined") ? "post" : config.method;
            this.async = (typeof config.async == "undefined") ? true : config.async;
            this.data = (typeof config.data == "undefined") ? null : config.data;
            
            this.progressBox.style.display = "block";
            this.initXHR();

        }
        
        PotatogUploadFile.prototype.initXHR = function()
        {
            var _this = this;
            this.xhr.open(this.method,this.url,this.async);
            var form = new FormData();
            var files = this.elObj.files;
            if(files.length == 0)
            {
                console.error("未选择文件");
            }
            
            for(var i in files)
            {
                form.append("file",files[i]);
            }
            
            if(_this.data != null)
            {
                for(var key in _this.data)
                {
                    form.append("data[" + key + "]",_this.data[key]);
                }
            }
            
            //上传开始
            this.xhr.upload.onloadstart = function()
            {
                _this.startTime = (new Date()).getTime();
                _this.preTime = (new Date()).getTime();
                _this.preLoad = 0;
            };
            
            //上传完成
            this.xhr.onload = function()
            {
                _this.callback(_this.xhr.responseText);
                _this.progressBox.style.display = "none";
            }
            
            //上传失败
            this.xhr.onerror =  function()
            {
                console.log("error");
                _this.progressBox.style.display = "none";
                
            }

            //上传进度
            this.xhr.upload.onprogress = function(evt)
            {

                _this.setProgressValue(evt.loaded / evt.total);
                
                var nowTime = (new Date()).getTime();
                var nowLoad = evt.loaded;

                var timeDelay = (nowTime - _this.preTime) / 1000;
                
                var loadedDelay = nowLoad - _this.preLoad;
                //b/s
                var speed = parseInt(loadedDelay / timeDelay);
                var preTime = Math.round((evt.total - evt.loaded) / speed);
                
                
                _this.count += 1;
                if(_this.count > 10)
                {
                    _this.count = 0;
                    _this.setSpeed(speed);
                    _this.setPredict(preTime);
                }
                _this.preTime = nowTime;
                _this.preLoad = nowLoad;
            }
            this.xhr.send(form);
        }
    })(window);

    本文参考:

    https://www.cnblogs.com/yuanlong1012/p/5127497.html

    http://www.ruanyifeng.com/blog/2012/08/file_upload.html

  • 相关阅读:
    windows如何查看删除记录
    nodejs 服务器 崩溃 2种解决办法
    WINDOWS常用端口列表
    windows端口
    普通交换机不需要任何设置,也不能设置
    二层网管交换机应用——访问控制功能管理内网电脑上网行为
    使用 Easy Sysprep v4(ES4) 封装 Windows 7教程
    A电脑的gho还原到B电脑上的驱动解决方案
    servlet 容器与servlet
    依赖注入与控制反转
  • 原文地址:https://www.cnblogs.com/potatog/p/9342448.html
Copyright © 2020-2023  润新知