html原生上传,一个基于HTML5及原生JS的文件上传组件--JohnUploader

587444d3b349

运行效果图

一、组件介绍

基本特点

基于HTML5的FileReader和FormData

可以完成多文件选择,并预览

完成文件的异步上传

原生XHR对象,适配多浏览器

代码

class JohnUploader{

url;

fileField;

vollay;

/**

*

* @param url 文件上传的地址

* @param fileField 一个"文件域"对象

* @param vollay 一个HTMLElement对象,做为img的容器

*/

constructor(url,fileField,vollay){

this.url=url

this.fileField=fileField

this.vollay=vollay

}

/**

* @param nf 一个新的"文件域对象"

* 由于"文件域"是不能够改变内容,所以需要改变这个属性

*/

setFileField(nf){

this.fileField=nf

}

/**

* 本函数的触发时机--文件域的改变事件

* 作用:在画廊中显示选中的图片

*/

selectionShow() {

this.vollay.innerHTML="";

let files = this.fileField.files;

for (let i = 0; i < files.length; i++) {

let file = files[i]

if(!file.isRemoved) {

let reader = new FileReader()

reader.readAsDataURL(file)

reader.onload = event=> {

let img = document.createElement('img')

img.src = reader.result

//点击图片删除(以后改成点击图片上的"删除logo")

img.onclick = event=> {

//为文件加入删除标记

file.isRemoved=true

//重新刷新画廊,从而不显示有删除标记的文件

this.selectionShow()

}

this.vollay.appendChild(img)

}

}

}

};

/**

* //根据给定的表单域,完成文件上传

* @param callback 文件上传完毕的回调函数,callback中的参数为:xhr.reponseText

*/

uploadFile(callback) {

let formData=new FormData();

let files = this.fileField.files;

if(files.length==0||files===null){

alert("没有选择上传文件!")

return;

}

for (let i = 0; i < files.length; i++) {

let file=files[i]

//如果文件没有加删除标记

if(!file.isRemoved)

formData.append('avatar',files[i],files[i].name);

}

let xhr=new XMLHttpRequest();

xhr.open("POST",this.url)

xhr.onreadystatechange=function(){

if(xhr.readyState==4){

callback(xhr.responseText)

}

}

xhr.send(formData)

}

}

二、组件使用演示

HTML部分

Title

img {

height: 100px;

margin: 5px;border: darkgreen 3px solid;padding: 2px;

}

这个文件域是被隐藏掉了

选择要上传的图片

上传画廊中的图片


已经上传的文件

//底部的测试代码

js测试代码

window.οnlοad=function(){

//抓取后台的图片列表

function fetchAllPhotos(url,callback){

let xhr=new XMLHttpRequest();

xhr.open("GET",url)

xhr.onreadystatechange=function(){

if(xhr.readyState==4){

let photos=JSON.parse(xhr.responseText)

callback(photos)

}

}

xhr.send(null)

}

/**

* 将抓取到的图片列表,在targetLocation中显示出来

* @param photos

* @param targetLocation

*/

function fetchAllPhotosCallback(photos,targetLocation){

targetLocation.innerHTML=''

photos.forEach(photo=>{

let img=document.createElement('img')

img.src='images/'+photo

targetLocation.appendChild(img)

})

}

let vollay = document.querySelector("#vollay")

let avatar = document.querySelector('[name="avatar"]')

let photoWall=document.querySelector('#photo-wall')

//这是主角JohnUploader

let uploader=new JohnUploader('upload',avatar,vollay)

//用来处理文件域清空的特殊情况,将来使用该克隆体,再进行克隆,替换掉avatar

let avtarClone=avatar.cloneNode(true)

//用于将"画廊复位"和将"文件域"进行复位

function reset(){

vollay.innerHTML = ''

let avatarClone2=avtarClone.cloneNode(true)

uploader.setFileField(avatarClone2)

avatar.after(avatarClone2)

avatar.remove()

avatar=avatarClone2

avatar.onchange = function(){

uploader.selectionShow()

}

}

//文件域的变化事件

avatar.onchange = function(){

uploader.selectionShow()

}

//抓取并显示后台的所有图片到照片墙

fetchAllPhotos('files',photos=>fetchAllPhotosCallback(photos,photoWall))

//使用button来完成"文件域"的选择文件功能

document.querySelector('#select-file').οnclick=()=>avatar.click()

//文件上传按钮的事件处理

document.querySelector('#upload-file').οnclick=()=> {

let innerAvatar=avatar

uploader.uploadFile(txt => {

//抓取并显示后台的所有图片到照片墙

fetchAllPhotos('files', photos => {

fetchAllPhotosCallback(photos, photoWall)

reset()

})

})

}

}

三、服务器部分Express+multer

项目依赖:

express

multer

项目结构

587444d3b349

项目结构

代码

//app.js

const fs=require('fs')

const express=require('express')

const http=require('http')

//文件上传中间件(指定上传的临时文件夹是/uploads)

const multer=require('multer')

var storage = multer.memoryStorage()

//磁盘临时文件的方案

// let upload = multer({ dest: 'uploads/' })

//内存缓存方案

let upload = multer({ storage: storage })

let app=express();

const FILE_PATH="public/images/"

//HttpServer服务的中间件(public目录下的index.html为首页)

app.use(express.static('public'))

//文件上传的处理(avatar是上传时的filedName)

app.post('/upload', upload.array('avatar',10), function (req, res, next) {

//req.body是普通表单域

//req.files或req.file,是文件域

let msg={

body:req.body,

files:req.files

}

//磁盘临时文件方案,将临时文件上传到/public/images中

// let output=fs.createWriteStream(FILE_PATH+req.file.originalname)

// let input=fs.createReadStream(req.file.path)

// input.pipe(output)

//内存缓存方案

req.files.forEach((file,index)=>{

fs.writeFile(FILE_PATH+file.originalname,file.buffer,function () {

console.log(file.originalname+"....完成"+index)

//最后一个文件处理完毕,直接显示数据

if (index==req.files.length-1){

res.json(msg)

}

})

})

})

//接收前端的请求,返回上传图片的列表

app.get("/files",function (req,res) {

fs.readdir('public/images',function (err,dir) {

res.json(dir)

})

})

//启动Express服务器

let server=http.createServer(app);

server.listen(8000,function () {

console.log("start server at port 8000")

})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/395383.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[20170617]vim中调用sqlplus.txt

[20170617]vim中调用sqlplus.txt --//以前写过一篇emacs下调用sqlplus的文章,一直想学emacs,受限制自己掌握vim,对学习它没有兴趣,原链接如下: --//http://blog.itpub.net/267265/viewspace-1309032/ --//实际上vim也有插件连接数据库,我觉得不好用,一直没这样用. --//今天在整…

centos redis验证_centos7中安装、配置、验证、卸载redis

本文介绍在centos7中安装、配置、验证、卸载redis等操作&#xff0c;以及在使用redis中的一些注意事项。一 安装redis1 创建redis的安装目录利用以下命令&#xff0c;切换到/usr/local路径cd /usr/local键入以下命令&#xff0c;新建一个redis目录&#xff0c;用于放置redis软件…

实习生解雇_我们解雇了我们的顶尖人才。 我们做出的最佳决定。

实习生解雇by Jonathan Solrzano-Hamilton乔纳森索洛萨诺汉密尔顿(JonathanSolrzano-Hamilton) 我们解雇了我们的顶尖人才。 我们做出的最佳决定。 (We fired our top talent. Best decision we ever made.) “You will never be able to understand any of what I’ve create…

微信企业号第三方应用开发[二]——创建应用

在应用套件里添加应用 当你创建完应用套件后&#xff0c;需要在套件配置应用&#xff0c;应用的信息填写如下。 基本信息&#xff1a; 信息项要求及说明应用Logo应用的Logo&#xff0c;小于2M&#xff0c;640*640&#xff0c;在授权页会被用于展示。应用名称应用的名称&#xf…

es6新增的html标签,javascript – 如何导入已在html中的标签中定义的es6模块?

我可以在我的html文件me.html中定义一个模块&#xff1a;import Atom from ./atom.js;console.log("definition of getAtom")export default function getAtom(){return new Atom(atom);}console.log("exported getAtom")另见>是否可以将该“匿名”模块…

jQ效果:简单的手风琴效果

实现效果如图所示&#xff1a; html结构&#xff1a; <div class"item_box box10"><div class"item_box_wp"><div class"voice_2"><ul><li class"li1" id"li1"><div class"fold"…

golang 日志分析_容器日志采集利器:Filebeat深度剖析与实践

在云原生时代和容器化浪潮中&#xff0c;容器的日志采集是一个看起来不起眼却又无法忽视的重要议题。对于容器日志采集我们常用的工具有filebeat和fluentd&#xff0c;两者对比各有优劣&#xff0c;相比基于ruby的fluentd&#xff0c;考虑到可定制性&#xff0c;我们一般默认选…

机器学习做自动聊天机器人_建立聊天机器人需要什么? 让我们找出答案。

机器学习做自动聊天机器人by Vanco Stojkov通过Vanco Stojkov 建立聊天机器人需要什么&#xff1f; 让我们找出答案。 (What does it take to build a chatbot? Let’s find out.) Without any delay, the image below shows what we are building:没有任何延迟&#xff0c;下…

UVA 11582 Colossal Fibonacci Numbers!【数学】

大一刚开始接触ACM就买了《算法竞赛入门经典》这本书&#xff0c;当时只能看懂前几章&#xff0c;而且题目也没做&#xff0c;粗鄙地以为这本书不适合自己。等到现在快大三了再回过头来看&#xff0c;发现刘老师还是很棒的&#xff01; 扯远了。。。 题意&#xff1a;问f[a^b]%…

Codeforces 919D Substring (拓扑图DP)

手动博客搬家: 本文发表于20180716 10:53:12, 原地址https://blog.csdn.net/suncongbo/article/details/81061500 给定一个\(n\)个点\(m\)条边的有向图&#xff08;不一定无环&#xff09;&#xff0c;每个点上有一个小写字母。要找一条路径&#xff0c;使得路径上出现次数最多…

layui自定义查询条件html页面,Layui的数据表格+springmvc实现搜索功能的例子_飛雲_前端开发者...

如下所示&#xff1a;主要在前端页面加&#xff1a;搜索ID&#xff1a;useridcontent搜索在reload:function () {var keyWord$("#keyWord").val();var keyType$("#key_type option:selected").val();table.reload(contenttable,{method:post,where:{keyWor…

mysql+keepalived 双主热备高可用

理论介绍&#xff1a;我们通常说的双机热备是指两台机器都在运行&#xff0c;但并不是两台机器都同时在提供服务。当提供服务的一台出现故障的时候&#xff0c;另外一台会马上自动接管并且提供服务&#xff0c;而且切换的时间非常短。MySQL双主复制&#xff0c;即互为Master-Sl…

java ldap userpassword 解密_Spring Boot中使用LDAP来统一管理用户信息

LDAP简介LDAP(轻量级目录访问协议&#xff0c;Lightweight Directory Access Protocol)是实现提供被称为目录服务的信息服务。目录服务是一种特殊的数据库系统&#xff0c;其专门针对读取&#xff0c;浏览和搜索操作进行了特定的优化。目录一般用来包含描述性的&#xff0c;基于…

第三章之枚举、注解

2019-01-22内容&#xff1a;枚举、注解一、自定义一个枚举类1 public class TestSeason {2 3 public static void main(String[] args) {4 Season spring Season.Spring;5 System.out.println(spring);6 }7 }8 public class Season {9 //将属性定…

html打开后默认浏览器页面,使用VBA打开默认浏览器中的html页面?

您可以使用Windows API函数ShellExecute来执行此操作&#xff1a;Option ExplicitPrivate Declare Function ShellExecute _Lib "shell32.dll" Alias "ShellExecuteA" ( _ByVal hWnd As Long, _ByVal Operation As String, _ByVal Filename As String, _Op…

数据科学r语言_您应该为数据科学学习哪些语言?

数据科学r语言Data science is an exciting field to work in, combining advanced statistical and quantitative skills with real-world programming ability. There are many potential programming languages that the aspiring data scientist might consider specializi…

Linux平台不同解压缩命令的使用方法

作者&#xff1a;郭孝星 微博&#xff1a;郭孝星的新浪微博 邮箱&#xff1a;allenwells163.com 博客&#xff1a;http://blog.csdn.net/allenwells github&#xff1a;https://github.com/AllenWell 一 .tar 解包 tar xvf FileName.tar 打包 tar cvf FileName.tar DirName 注意…

unity中怎么做河流_【干货】工作中怎么做工业设计的?(一)

最近在找工作&#xff0c;一直在看招聘信息。看到工业设计工资还是蛮高的。应届毕业生一般是4-6K&#xff0c;1-3年工作经验是6-8K&#xff0c;3年以后的差不多是8K以上了。我没有嫉妒羡慕恨&#xff0c;发誓&#xff0c;真的没有。工业设计已经被重视&#xff0c;未来的道路会…

[易学易懂系列|golang语言|零基础|快速入门|(一)]

golang编程语言&#xff0c;是google推出的一门语言。 主要应用在系统编程和高性能服务器编程&#xff0c;有广大的市场前景&#xff0c;目前整个生态也越来越强大&#xff0c;未来可能在企业应用和人工智能等领域占有越来越重要的地位。 本文章是【易学易懂系列|编程语言入门】…

APUE学习之三个特殊位 设置用户ID(set-user-ID),设置组ID(set-group-ID),sticky...

设置用户ID&#xff08;set-user-ID&#xff09;&#xff0c;设置组ID&#xff08;set-group-ID&#xff09;&#xff0c;stickyset-user-ID: SUID当文件的该位有设置时&#xff0c;表示当该文件被执行时&#xff0c;程序具有文件所有者的权限而不是执行者的权限。这样说有点绕…