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,一经查实,立即删除!

相关文章

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

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

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;我们一般默认选…

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

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

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

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

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

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

spi收发时的寄存器sr不变_「正点原子Linux连载」第二十七章SPI实验(二)

1)实验平台&#xff1a;正点原子Linux开发板2)摘自《正点原子I.MX6U嵌入式Linux驱动开发指南》关注官方微信号公众号&#xff0c;获取更多资料&#xff1a;正点原子文件bsp_spi.c中有两个函数&#xff1a;spi_init和spich0_readwrite_byte&#xff0c;函数spi_init是SPI初始化函…

[JSOI2018]潜入行动

题解 一道思路不难但是写起来很麻烦的树形背包 我们发现每个节点有很多信息需要保留 所以就暴力的设\(f[u][j][0/1][0/1]\)表示点u的子树分配了j个监察器,点u有没有被控制,点u放没放监察器 然后就分四种情况暴力讨论就好了 注意背包的时候要卡常数 代码 #include<cstdio>…

css。元素样式、边框样式

1.外边距  margin 缩写形式&#xff1a; margin&#xff1a;上边距  右边距  下边距  左边距 margin&#xff1a;上下边距  左右边距 margin&#xff1a;上边距  左右边距  下边距 2.内边距  padding 缩写形式&#xff1a; padding&#xff1a;上边距  右边距…

C# 动态创建数据库三(MySQL)

前面有说明使用EF动态新建数据库与表&#xff0c;数据库使用的是SQL SERVER2008的&#xff0c;在使用MYSQL的时候还是有所不同 一、添加 EntityFramework.dll &#xff0c;System.Data.Entity.dll &#xff0c;MySql.Data, MySql.Data.Entity.EF6 注意&#xff1a;Entity Frame…

如何用计算机管理员权限,教你电脑使用代码添加管理员权限的详细教程

我们在使用电脑运行某些软件的时候&#xff0c;可能需要用到管理员权限才能运行&#xff0c;通常来说直接点击右键就会有管理员权限&#xff0c;但最近有用户向小编反馈&#xff0c;在需要管理员权限的软件上点击右键没有看到管理员取得所有权&#xff0c;那么究竟该如何才能获…

activiti 5.22的demo运行

activiti 5.22的demo运行 从github上clon下来的activiti项目,运行demo项目activiti-webapp-explorer2时&#xff0c;在使用到流程设计工作区&#xff0c;选取activiti modeler作为设计器的时候报错。 从下面的报错信息中发现&#xff0c;请求路径http://localhost:8080/activit…

内是不是半包围结构_轻钢别墅的体系结构

一、轻钢别墅介绍1、轻钢别墅的屋面系统轻钢别墅屋面系统是由屋架、结构OSB面板、防水层、轻型屋面瓦&#xff08;金属或沥青瓦&#xff09;组成的。轻钢结构的屋面&#xff0c;外观可以有多种组合。材料也有多种。在保障了防水这一技术的前提下&#xff0c;外观有了许多的选择…

hive 去重 字符串_hive函数

Hive是建立在 Hadoop 上的数据仓库基础架构,定义了简单的类 SQL 查询语言(HQL)函数分类&#xff1a;简单内置函数&#xff1a;数学函数&#xff0c;字符函数&#xff0c;日期函数&#xff0c;条件函数&#xff0c;聚合函数。高级内置函数&#xff1a;行列转换函数&#xff0c;分…

【Python3爬虫】为什么你的博客没人看呢?

我相信对于很多爱好和习惯写博客的人来说&#xff0c;如果自己的博客有很多人阅读和评论的话&#xff0c;自己会非常开心&#xff0c;但是你发现自己用心写的博客却没什么人看&#xff0c;多多少少会觉得有些伤心吧&#xff1f;我们今天就来看一下为什么你的博客没人看呢&#…

泰安高考2021成绩查询,泰安高考成绩查询入口2021

高考结束之后&#xff0c;为了方便大家进行高考成绩的查询&#xff0c;下面跟着出国留学网小编来一起看看“泰安高考成绩查询入口2021”&#xff0c;仅供参考&#xff0c;希望对大家有帮助。2021山东高考成绩查询时间及志愿填报时间根据山东2021年夏季高考须知&#xff0c;2021…

用GitHub Issue取代多说,是不是很厉害?

2019独角兽企业重金招聘Python工程师标准>>> 摘要: 别了&#xff0c;多说&#xff0c;拥抱Gitment。 2017年6月1日&#xff0c;多说正式下线&#xff0c;这多少让人感觉有些遗憾。在比较了多个博客评论系统&#xff0c;我最终选择了Gitment作为本站的博客评论系统&a…

【动态规划】Vijos P1313 金明的预算方案(NOIP2006提高组第二题)

题目链接&#xff1a; https://vijos.org/p/1313 题目大意&#xff1a; m(m<32000)金钱&#xff0c;n&#xff08;n<60&#xff09;个物品&#xff0c;花费vi&#xff0c;价值vi*ci,每个物品可能有不超过2个附件&#xff0c;附件没有附件。 题目思路&#xff1a; 【动态规…

计算机网络应用答题卡,2013-2014学年第2学期11级计算机网络技术毕业考试试卷

2013-2014学年第2学期11级《计算机网络技术》课程毕业考试试卷得分&#xff1a;一、单项选择题&#xff1a;(每题1分&#xff0c;共30分&#xff0c;答案必须写在后面的选择题答题卡内&#xff0c;否则不得分)1、计算机网络可以按网络的覆盖范围来划分&#xff0c;以下()不是按…

为什么那些每三年跳一次槽的人越跳越好? - 震撼

现在&#xff0c;人们已经放下了对跳槽的偏见。这是一件好事。之前。假设你每几年换一次工作&#xff0c;人们会认为你的简历上有 “污点”。面试官会认为你无法胜任一份工作。与同事相处不好。或者你对公司不忠诚&#xff0c;不能承担任务&#xff0c;等等。 这样的想法非常快…