上传图片,多图上传,预览功能,js原生无依赖

最近很好奇前端的文件上传功能,因为公司要求做一个支持图片预览的图片上传插件,所以自己搜了很多相关的插件,虽然功能很多,但有些地方不能根据公司的想法去修改,而且需要依赖jQuery或Bootstrap库,所以我就想学下图片上传的原理,试着做一个原生无依赖,而且足够灵活的图片上传插件。话不多说,开整。

1. 大体思路

1.1 首先我们需要考虑用户如何使用我们的插件。

用户引入插件代码后,只需要像下面这样,设置一些参数,然后执行一个方法就生成一个图片上传组件。

<div id="upload"></div> // 这是用来生成图片上传组件的div
<script>
// 设置参数 var options = { path: '/', // 上传图片时指定的地址路径,类似form变淡的action属性 onSuccess: function (res) { // 上传成功后执行的方法,res是接收的ajax响应内容 console.log(res); }, onFailure: function (res) { // 上传失败后执行的方法,res是接收的ajax响应内容 console.log(res); } } // 执行生成图片上传插件的方法, 第一个参数是上面提到的准备生成组件的div选择器,第二个参数是设置的组件信息,执行方法后返回一个函数指针,指向执行上传功能的函数,通过把执行上传功能的函数暴露出来,用户就可以自己控制何时上传图片了。 var upload = tinyImgUpload('#upload', options); </script>

1.2 代码设计

我们需要思考用户如何引入我们的插件代码。
插件代码应该分为两个文件,一个CSS文件(tinyImgUpload.css),用于定义组件的基本样式,此外用户可以根据自己的想法自己DIY样式,另一个是控制功能逻辑的js文件(tinyImgUpload.js)。用户引入这两个文件后,就可以实现图片上传组件了。

2. 具体实现

具体实现的时候,主要涉及到两个地方,一个是读取本地文件,实现图片上传前可以预览的功能,一个是图片上传功能。

2.1 读取本地文件实现预览

这里用到了html5的File API,使用这个API可以在客户端验证上传的文件类型,限制文件大小,当然,在这里我们主要用到FileReader接口来读取文件,Filereader.readAsDataURL()返回的事件对象的result属性就是将文件编码为base64的数据地址,类似下面这样的,把他赋值给src属性,图片就显示出来了。

具体代码如下,完整代码可以从这里下载(tinyImgUpload.js )

// 预览图片
//处理input选择的图片
function handleFileSelect(evt) { var files = evt.target.files; for(var i=0, f; f=files[i];i++){ // 过滤掉非图片类型文件 if(!f.type.match('image.*')){ continue; } // 过滤掉重复上传的图片 var tip = false; for(var j=0; j<(ele.files).length; j++){ if((ele.files)[j].name == f.name){ tip = true; break; } } if(!tip){ // 图片文件绑定到容器元素上 ele.files.push(f); var reader = new FileReader(); reader.onload = (function (theFile) { return function (e) { var oDiv = document.createElement('div'); oDiv.className = 'img-thumb img-item'; // 向图片容器里添加元素 oDiv.innerHTML = '<img class="thumb-icon" src="'+e.target.result+'" />'+ '<a href="javscript:;" class="img-remove">x</a>' ele.insertBefore(oDiv, addBtn); }; })(f); reader.readAsDataURL(f); } } } // input#img-file-input是一个隐藏的上传图片的input控件,当选择图片的时候会触发change事件 document.querySelector('#img-file-input').addEventListener('change', handleFileSelect, false);

2.2 上传图片

2.2.1 准备文件对象

上传文件之前,我们需要考虑如何保存用户已经选择的文件对象,由于用户可能多次选择,也可能在上传之前又删除了几个图片,所以需要有一个地方实时保存图片信息,并且要和预览的图片保持同步,预览显示有哪几张图片,这个地方就存储几张图片。我采用的方式是将文件信息组装成一个数组,然后绑定到组件元素(#img-container)的自定义属性上,上面代码中的“ele.files.push(f)”做的就是这件事。

2.2.2 文件对象我们准备好后,下一步就是上传了

ajax是不能直接上传文件对象的,我们可以通过FormData对象,FormData是XMLHttpRequest Level 2添加的一个新接口,使用一系列的键值对来模拟一个完整的表单,然后使用XMLHttpRequest异步发送这个"表单"。具体代码如下。

// 上传图片
function uploadImg() { var xhr = new XMLHttpRequest(); var formData = new FormData(); for(var i=0, f; f=ele.files[i]; i++){ formData.append('files', f); } xhr.onreadystatechange = function (e) { if(xhr.readyState == 4){ if(xhr.status == 200){ options.onSuccess(xhr.responseText); }else { options.onFailure(xhr.responseText); } } } xhr.open('POST', options.path, true); xhr.send(formData); }

2.3 设置样式

我们写了一个基本的布局样式作为默认样式,用户可以根据自己的需求进行DIY。这里是完整的样式文件(tinyImgUpload.css )。
基本的效果图如下。

如果我们想触发上传图片,可以把tinyImgUpload('#upload', options)返回的upload方法绑定到一个按钮上,监听点击事件。

<button class="submit">submit</button> <script> document.getElementsByClassName('submit')[0].onclick = function (e) { upload(); } </script>

这样当我点击图片的时候,图片就会上传,交给服务器端处理了。

上传按钮

服务器接收的图片

为了测试图片上传好不好用,我自己搭建了一个图片接收的服务器,使用的是node.js,通过multer实现,如果大家感兴趣可以点击这里。

3 总结

图片上传的关键部分就是如何读取本地文件实现预览,以及通过FormData对象构造一个表单对象实现ajax异步上传文件。目前这个插件的功能还不够完善,我把它放到了Github上(https://github.com/gitwd/tinyImgUpload),后续会慢慢优化,欢迎大家提出宝贵意见。

转载于:https://www.cnblogs.com/libin-1/p/6508600.html

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

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

相关文章

mongodb java id 查询数据_java 用 _id 查找 MongoDB 下的数据

找网上的资料看了下增删改查&#xff0c;等日后补上。已经实现了数据的插入&#xff0c;现在想通过 _id属性来查找数据。一开始看到 类似 55b321df715cc162076eb466 这么一长串的内容觉得是string类型。但是发现并不能搜索到结果&#xff0c;在网上搜到了解决方案&#xff1a;S…

js中的面向对象入门

http://www.cnblogs.com/chenmeng0818/p/6508755.html 什么是对象 我们先来看高程三中是如何对对象进行定义的 "无序属性的集合&#xff0c;其属性可以包括基本值、对象或者函数"&#xff0c;对象是一组没有特定顺序的的值。对象的没个属性或方法都有一个俄名字&…

maven 父maven_Maven不会吮吸。 。 。 但是Maven文件会

maven 父maven我不会参加整个Maven辩论&#xff0c;但可以说我是所有最佳实践的坚定支持者&#xff0c;对我而言&#xff0c;Maven是最佳实践的体现。 我的意思是说&#xff0c;Maven是围绕特定的最佳实践构建方法构建的。 注意&#xff0c;我说了一种特定的最佳实践构建方法。…

java maven部署_eclipse中maven项目部署到tomcat

下面就一一介绍这几种部署方式&#xff1a;1.打war包到tomcat/webapps目录这种方式其实跟非maven项目没什么区别&#xff0c;就是打包的方式不同之后在target目录下会生成war包&#xff0c;复制到tomcat/webapps目录即完成部署。2.使用tomcat-maven插件&#xff0c;在pom.xml的…

word 论文排版 —— 按指定格式章节的自动编号

在word中如何实现章节标题自动编号 标题样式与标题的编号是两个步骤&#xff0c;为标题建立编号是在为标题样式确定的基础后进行的。这是显而易见的&#xff0c;也即只有先定义了多级标题&#xff08;也可使用 word 自带的标题样式&#xff09;&#xff0c;才可为这些多级标题自…

vb 获取mysql表第一行数据_vb如何将远程获取的数据插入本机数据表中

双击按钮添加如下代码Private Sub Command1_Click()Dim objRemoteConn As New ADODB.ConnectionDim objLocalConn As New ADODB.ConnectionDim objRs As ADODB.RecordsetDim strSql As StringobjRemoteConn.Open "providerSQLOLE…

ASP渲染下拉框使时间依次减少

<% xyear(now()) yyear(now())-1 Do While y>2002%><li><a href"#2015" class"treeview-time"><%y%></a></li><% yy-1 loop%>转载于:https://www.cnblogs.com/mazey/p/6512893.html

Spring Cloud对Hystrix的支持

Spring Cloud项目为Netflix OSS Hystrix库提供了全面的支持。 之前我已经写过有关如何使用原始Hystrix库包装远程调用的文章。 在这里&#xff0c;我将探讨如何将Hystrix与Spring Cloud结合使用 基本 实际上并没有什么大不了的&#xff0c;这些概念仅在特定于Spring引导的增强…

OA系统部署短信过程

安装dotNetFx40_Client_setup.exe插件 安装mysql_installer_community_V5.6.21.1_setup.1415604646.msi数据库 根据数据库版本安装相应驱动&#xff08;64位或者32位系统&#xff09; 安装mysql-connector-odbc-5.3.7-winx64.msi驱动&#xff08;ODBC&#xff09;工具 安装mysq…

centos6配置mysql5.7_CentOS 6/7 下 MySQL 5.7 安装部署与配置

一、前言1、本教程主要内容MySQL 5.7安装(yum)MySQL 5.7 ROOT账号密码修改MySQL 5.7基础使用与配置MySQL shell管理常用语法示例(用户、权限等)MySQL字符编码配置2、本教程环境信息与适用范围环境信息软件版本CentOS7.4 ReleaseMySQL5.7适用范围软件版本CentOSCentOS 6 & C…

hadoop伪分布式搭建 java_hadoop2.2.0伪分布式搭建

第一步&#xff1a;安装jdk我的linux版本是centos7&#xff0c;使用最简单的安装方式&#xff0c;这里首先说一下&#xff0c;由于系统会预装openjdk版本等其他各种版本&#xff0c;首先要做的是清除这些版本&#xff0c;然后iu安装oracle的jdk版本1.1 查看所有jdk版本并删除其…

北斗有 35 颗卫星,而 GPS 有 24 颗卫星,为什么二者数量不同?

作者&#xff1a;知乎用户链接&#xff1a;https://www.zhihu.com/question/21092045/answer/17164418来源&#xff1a;知乎著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。反对目前的两个不靠谱回答&#xff01;需要的卫星数目和别人占坑没有…

可行的DeltaSpike教程

在一个最近的项目中&#xff0c;我遇到了一个有趣的问题&#xff1a;采用被赋予单个对象的服务方法&#xff0c;并在一个夜间过程的上下文中重用相同的代码&#xff0c;该过程独立于应用程序而在数千个相同类型的对象上运行。 试图在两个地方维护如此大小和复杂性的相同过程真…

2017/3/8 函数指针/事件/委托....

函数指针&#xff1a; 定义&#xff1a;函数指针是指向函数的指针变量。 因而“函数指针”本身首先应是指针变量&#xff0c;只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样&#xff0c;这里是指向函数。 函数指针有两个用途&#xff1a;调用函数…

java finalize 析构_close,析构函数和finalize:Java矛盾

try { FileInputStream in new FileInputStream(filename);BufferedReader readernew BufferedReader(new InputStreamReader(in));String line;while((linereader.readLine())!null){// read the file}}catch (Exception e) {System.out.println(e);}但是如果我尝试将命令添加…

sharesdk短信验证码的集成

在ShareSDK官网http://mob.com/注册并创建Android应用.申请APP_key,下载SDK等 根据官网开发文档导入SDK,目录结构如下 将以上文件按需放入Android Studio项目所要使用SMSSDK的Module所在的Libs里面&#xff0c;再在Module的build.gradle里面将libs加入仓库&#xff08;reposito…

java四神兽_SpringCloud五大神兽之Eureka

注册中心概述什么是注册中心&#xff1f;相当于服务之间的‘通讯录’&#xff0c;记录了服务和服务地址之间的映射关系。在分布式架构中服务会注册到这里。当服务需要调用其他服务时&#xff0c;就在注册中心找到其他服务的地址&#xff0c;进行调用注册中心的主要作用&#xf…

Mockito入门

本文是我们名为“ 用Mockito进行测试 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入了解Mockito的魔力。 您将了解有关“模拟”&#xff0c;“间谍”和“部分模拟”的信息&#xff0c;以及它们相应的Stubbing行为。 您还将看到使用测试双打和对象匹配器进行验证的过…

windows下dubbo-admin和zookeeper安装部署

1. 概述 ZooKeeper是Hadoop的正式子项目&#xff0c;它是一个针对大型分布式系统的可靠协调系统&#xff0c;提供的功能包括&#xff1a;配置维护、名字服务、分布式同步、组服务等。ZooKeeper的目标就是封装好复杂易出错的关键服务&#xff0c;将简单易用的接口和性能高效、…

jpush java api_JPush極光推送Java服務器端API

產品功能說明極光推送(JPush)是一個端到端的推送服務&#xff0c;使得服務器端消息能夠及時地推送到終端用戶手機上&#xff0c;讓開發者積極地保持與用戶的連接&#xff0c;從而提高用戶活躍度、提高應用的留存率。極光推送客戶端支持 Android, iOS 兩個平台。本 Android SDK …