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

上传图片,多图上传,预览功能,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属性,图片就显示出来了。
base64图片的样子
具体代码如下,完整代码可以从这里下载(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 )。
基本的效果图如下。
demo样式
如果我们想触发上传图片,可以把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),后续会慢慢优化,欢迎大家提出宝贵意见。

4 参考目录

https://www.html5rocks.com/en/tutorials/file/dndfiles/
http://codecloud.net/9276.html
http://www.zhangxinxu.com/wordpress/2011/09/%E5%9F%BA%E4%BA%8Ehtml5%E7%9A%84%E5%8F%AF%E9%A2%84%E8%A7%88%E5%A4%9A%E5%9B%BE%E7%89%87ajax%E4%B8%8A%E4%BC%A0/
https://cnodejs.org/topic/50ce2bbb637ffa415589a50f

原网址  https://www.cnblogs.com/woodyblog/p/6508524.html

js实现上传图片实时预览

html部分

<img alt=""  id="img"  >
<input  type="file" onchange='PreviewImage(this)' >
  • 1js 需要引入 jquery
//在type为file的input上面添加这个onchenge事件方法名为PreviewImage(this)
function PreviewImage(imgFile) 
{ 
    //使用这个方法来临时创建一个文件的链接,参数是一个file或者blob
    var path = URL.createObjectURL(imgFile.files[0]);
    //将链接赋值给上面的图片src路径
    $("#img").prop("src",path)
    //销毁上面创建的链接
    //URL.revokeObjectURL(path);
 } 

可能需要考虑浏览器兼容性问题   用下面类似的方法

file = jQuery('.file')[0].files[0];
    //添加图片路径到img src中进行预览
    jQuery('#iamge').attr('src',getObjectURL(file));
    //不同浏览器下的路径不同
     function getObjectURL(file) {
          var url = null;
          if (window.createObjectURL != undefined) { // basic
            url = window.createObjectURL(file);
          } else if (window.URL != undefined) { // mozilla(firefox)
            url = window.URL.createObjectURL(file);
          } else if (window.webkitURL != undefined) { // webkit or chrome
            url = window.webkitURL.createObjectURL(file);
          }
          return url;
        }

 

源网址:https://blog.csdn.net/chenyidong521/article/details/53670915

 

文件上传 一直是个需要解决的问题 ,现在就总结一下

 

常见的思路有两种:一是将图片上传至服务器的临时文件夹中,并返回该图片的url,然后渲染在html页面;另一种思路是,直接在本地内存中预览图片,用户确认提交后再上传至服务器保存。

这两种方法各有利弊,方法一很明显,浪费流量和服务器资源;方法二则加重了浏览器的负担,并且对浏览器的兼容性要求更高(在某些低版本中的IE浏览器不支持)。

 

 利用 fileupload.js

这样的操作是 点击上传,选择文件之后就开始上传,这样其实并不好。假如上传错了,在重新上传 会造成多余图片的上传。

需要引入的js文件
顺序不可乱!!
 

编写html代码

编写input标签,可以进行图片选择

<input id="fileupload" type="file" name="file">

编写一个div显示进度条,初始长度为0%

<div class="bar" style="width: 0%;"></div>

编写一个img标签显示上传之后的图片

<img id="uploadimg" src="__PUBLIC__/images/bg.jpg" width="400px" height="408px"/>

Js代码

$('#fileupload').fileupload({

       dataType: 'json',

        url: "<%=request.getContextPath() %>/video/bgmUpload.action",//文件的后台接受地址

        //设置进度条

        progressall: function (e, data) {

            var progress = parseInt(data.loaded / data.total * 100);

            $('#progress .bar').css(

                'width',

                progress + '%'

            );

        },

        //上传完成之后的操作,显示在img里面

        done: function (e, data){

            $("#uploadimg").attr({src: data.result.pic_url});

            $("#uploadimg").css({width: "400px", height: "400px"});

        }

    });

 

上面是从网上找到的例子 下面是自己测试过的

 

 

数据存放在 data.result对象里

 

后端的代码

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值