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="width: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
js 文件异步上传 显示进度条 显示上传速度 预览文件的更多相关文章
- JS原生上传大文件显示进度条-php上传文件
JS原生上传大文件显示进度条-php上传文件 在php.ini修改需要的大小: upload_max_filesize = 8M post_max_size = 10M memory_li ...
- Jquery.Uploadify实现批量上传显示进度条 取消 上传后缩略图显示 可删除
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="UpLoad.aspx.cs&q ...
- xutils工具上传日志文件--使用https并且带进度条显示
package logback.ecmapplication.cetcs.com.myapplication; import android.app.Activity; import android. ...
- 【Winform】使用BackgroundWorker控制进度条显示进度
许多开发者看见一些软件有进度条显示进度,自己想弄,项目建好后发现并没有自己想象中的那么简单...看了网上很多教程后,写了一个小Demo供网友们参考~~,Demo的网址:http://pan.baidu ...
- Asp.Net实现无刷新文件上传并显示进度条(非服务器控件实现)(转)
Asp.Net实现无刷新文件上传并显示进度条(非服务器控件实现) 相信通过Asp.Net的服务器控件上传文件在简单不过了,通过AjaxToolkit控件实现上传进度也不是什么难事,为什么还要自己辛辛苦 ...
- HTML+JS实现视频上传显示进度条
示例代码: css部分: #content{border: 1px solid saddlebrown;padding: 16px;border-radius: 2px} .list {top: 15 ...
- Extjs 使用fileupload插件上传文件 带进度条显示
一.首先我们看看官方给出的插件的解释: 一个文件上传表单项具有自定义的样式,并且可以控制按钮的文本和 像文本表单的空文本类似的其他特性. 它使用一个隐藏的文件输入元素,并在用户选择文件后 在form提 ...
- Ajax上传文件进度条显示
要实现进度条的显示,就要知道两个参数,上传的大小和总文件的大小 html5提供了一个上传过程事件,在上传过程中不断触发,然后用已上传的大 小/总大小,计算上传的百分比,然后用这个百分比控制div框的显 ...
- python实现socket上传下载文件-进度条显示
在python的socket编程中,可以实现上传下载文件,并且在下载的时候,显示进度条,具体的流程如下图所示: 1. 服务器端代码如下: [root@python 519]# cat server.p ...
随机推荐
- 九、Linux上软件安装
1. 在Linux上安装JDK: [步骤一]:上传JDK到Linux的服务器. * 上传JDK * 卸载open-JDK java –version rpm -qa | grep java rpm - ...
- RPA与AI_新技术能给企业业务流程带来怎样的价值?
RPA助力于流程自动化蜕变 RPA是Robotic Process Automation的缩写,意为: 将机器人作为虚拟劳动力,依照预先设定的程序与现有用户系统进行交互并完成设定好的任务流程.RPA可 ...
- Python-接口自动化(三)
python基础知识(三) (三)函数 1.函数 函数的语法: def 函数名(): 函数体 a.函数的关键字是def,函数体就是你希望这个函数帮你实现什么功能,函数名命名需要遵循的原则是以小写字母分 ...
- 深度解析synchronized的实现原理(并发一)
一.synchronized实现原理 1.synchronized实现同步的基础: 1).普通同步方法:锁是当前实例对象 2).静态同步方法:锁是当前类的class对象 3).同步方法块:锁是括号里面 ...
- 连接MySQL常用工具
database.properties 如下:url中coursesystem为将要连接的数据库名:username为该数据库设置权限时的用户名:如果设置了密码,再添一项password=你的密码 d ...
- linux介绍、命令(基本命令、常用命令、使用方法、基本格式)
操作系统(科普章节) 目标 了解操作系统及作用 1. 操作系统(Operation System,OS) 一个例子说明操作系统 操作系统作为接口的示意图 没有安装操作系统的计算机,通常被称为 裸机 如 ...
- 语言模型(N-Gram)
问题描述:由于公司业务产品中,需要用户自己填写公司名称,而这个公司名称存在大量的乱填现象,因此需要对其做一些归一化的问题.在这基础上,能延伸出一个预测用户填写的公司名是否有效的模型出来. 目标:问题提 ...
- 性能测试LR学习笔录 -2
LoadRunner基本测试流程: 制定性能测试计划(部分) -> 创建测试脚本 -> 编译.运行测试脚本 -> 创建场景 - > 运行.监控场景.收集数据 -> 生 ...
- mysql 的存储过程 循环 变更某个表里的字段
/*Navicat MySQL Data Transfer Source Server : localhost_3306Source Server Version : 50505Source Host ...
- 使用TkbmMWThreadList实现线程安全列表
2008年的2.90.00版本,作者实现了TkbmMWThreadList,之后在kbmMW 4.40.00版本,作者将TkbmMWThreadList改成了泛型版本,用以实现线程安全的列表.要使用T ...