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.pswp.cn/news/395383.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/395383.shtml
英文地址,請注明出處:http://en.pswp.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;程序具有文件所有者的權限而不是執行者的權限。這樣說有點繞…