图片如何无刷新的上传到服务器呢? 继前两篇文章后, 我们来实战一下如何无刷新的异步上传图片, 我们还是先看一下效果
在实战前呢, 我们需要做些准备工作. 比如说, 了解一下 FormData 对象
"FormData 对象用以将数据编译成键值对, 以便用 XMLHttpRequest 来发送数据. 其主要用于发送表单数据, 但亦可用于发送带键数据 (keyed data), 而独立于表单使用. 如果表单 enctype 属性设为 multipart/form-data , 则会使用表单的 submit() 用来提交表单, 这个方法和提交表单按钮很类似.")方法来发送数据, 从而, 发送数据具有同样形式."
这是官方的讲解, 我来说一下我的理解, 我们 new 一个 FormData( $(form) )对象时, 它会帮我们把 form 表单里的数据封装成键值对的形式, 以前我们都时用 input 的 submit 进行提交数据, 当我们拿到这个 form 对象的时候, 我们就可以用 ajax 模拟 input 的 submit 提交, 既然知道了这些, 我们就开始一步步的编程吧.
我们先完善一下界面, 看一下下面的代码
这是 body 里的内容, 不要忘了 form, 只是没有了 action,enctype 属性也要设置好, 我的上一篇文章有对 enctype 的讲解 图片上传并回显后端篇
- <body>
- <form id="formTag1" enctype="multipart/form-data">
- <div class="uploadImgBtn" id="uploadImgBtn">
- <input class="uploadImg" type="file" name="file" id="file1">
- </div>
- </form>
- </body>
这是 CSS 里的内容
- <style>
- .uploadImgBtn {
- width: 100px;
- height: 100px;
- cursor: pointer;
- position: relative;
- background: url("img/plus.png") no-repeat;
- -webkit-background-size: cover;
- background-size: cover;
- }
- .uploadImgBtn .uploadImg {
- position: absolute;
- right: 0;
- top: 0;
- width: 100%;
- height: 100%;
- opacity: 0;
- cursor: pointer;
- }
- .pic {
- width: 100px;
- height: 100px;
- }
- .pic img {
- width: 100%;
- height: 100%;
- }
- </style>
基本的样式都已经编写完成, 我们来参观一下吧
好了, 我们开始编写我们的 jquery 代码吧, 在编写之前我们理一下思路, 当用户选择好图片时, 即 input 的 change 事件触发时, 我们就把图片上传到服务器, 服务端返回图片的 url, 我们拿到这个 url 时, 把它设置为我们 input 外面盒子的背景图. 既然知道了思路我们就编写一下代码吧
- <script>
- $(document).ready(function(){
- $("#file1").on("change", upload );
- })
- function upload(){
- /**
- * 我们存一下 this 对象,
- * 我们将在 ajax 的回调函数中,
- * 将要用这个对象,
- * 用它来改变父盒子的背景图
- *
- */
- var self = this;
- // 如果不理解我写的, 可以看看我的前几篇文章
- $.ajax({
- url: "/UpImg/upload",
- type: "post",
- dataType: "json",
- cache: false,
- data: new FormData($("#formTag1")[0]),
- processData: false,// 不处理数据
- contentType: false, // 不设置内容类型
- success: function(data){
- /*
- 后端返回的数据格式为
- {"url": "xxxxxx"}
- */
- $(self).parent().css({
- "background-image": "url("+data.url+")"
- })
- }
- })
- }
- </script>
我们把 change 事件的执行函数独立出来, 因为我们可能还需要用到这个函数. 函数也没有什么难点, 就是保存一个 this 对象, 加一个 ajax. 我们来看一下效果图
我们已经实现了 change 事件触发时, 我们把图片上传到服务器, 我们也可以改变我们已经选择好的图片, 到这里肯定还没有结束. 因为用户只是选择了一张图片, 如果我们的业务需要用户上传多张图片呢, 那我们这个肯定就不满足要求了, 我们需要再给我们的代码添加一些功能. 比如说, 当用户选择好一张后, 再生成一个 form->input 标签, 然后就这样递归; 但我们还需要加一些条件, 就是当用户改变已经选择好的图片时, 我们不能生成 form->input 标签. 好了需求大概就是这样的.
我们来理一下思路:
1, 我们需要给 form 标签外面添加一个盒子, 我们把所有生成的 form 标签都放里面.
2, 我们需要有一个计数器, 记录 form 的个数, 也是通过这个我们可以给 form 和 input 设置不同的 id
3, 我们需要判断当前 change 事件是第几个, 如果它的 id 中的数值部分和 count 一样, 我们就新生成一个 form, 否则就返回
我们先看一下我们的 html 部分
- <body>
- <div id="formBox">
- <form id="formTag1" enctype="multipart/form-data">
- <div class="uploadImgBtn" id="uploadImgBtn">
- <input class="uploadImg" type="file" name="file" id="file1">
- </div>
- </form>
- </div>
- </body>
我们来编码实现一下 js
- <script>
- // 作为第几个 form 的标志
- var count = 1;
- $(document).ready(function(){
- $("#file1").on("change", upload );
- });
- function upload(){
- var self = this;
- // 获得它是第几个 form 表单
- var num = this.getAttribute("id").replace(/[a-zA-Z]/g,"");
- // 构造 form 的选择器
- var $form = "#formTag" +num;
- $.ajax({
- url:"/UpImg/upload",
- type:"post",
- dataType:"json",
- cache:false,
- data: new FormData($($form)[0]),
- processData: false,// 不处理数据
- contentType: false, // 不设置内容类型
- success:function(data){
- // 设置背景为我们选择的图片
- $(self).parent().css({
- "background-image": "url("+data.url+")"
- });
- // 我们再生成一个 form
- if(count == num ){
- //count 计数加 1
- count +=1;
- var str = '<form id="formTag'+count+'" enctype="multipart/form-data">'+'<div class="uploadImgBtn" id="uploadImgBtn">'+'<input class="uploadImg" type="file" name="file" id="file'+count+'">'+
- '</div>'+
- '</form>';
- // 向最外面的盒子添加 form
- $("#formBox").append($(str));
- // 构造 input 的选择器
- var $sel = "#file"+count;
- // 为新生成的 input 绑定 change 事件
- $($sel).on("change", upload );
- }else{
- // 如果不等于
- return false;
- }
- }
- });
- }
- </script>
这样的话我们基本就实现了我们的效果, 就如开头中的效果, 这个是可以无限添加 form 的, 到时候可以给 count 设置一个上界, 根据自己的业务来调整吧, 到此我们的图片上传并回显系列就算完结了;
听说 520 快到了, 我们是不是需要 new 一个会说话的对象呢, 520 的时候我们就来实战 new 一个对象吧, 也是作为一个礼物送给大家呢(手动滑稽)
图片上传并回显系列
如何用 input 标签上传多个图片并回显
图片上传并回显后端篇
来源: http://www.jianshu.com/p/18206a94fee5