纯原生多图片上传

前言:现在上传图片的插件一波又一波,当然框架中也有图片上传的组件(antd 、elementui),但是总有需求与这些组件不相符(难受)作者是react党,常用就是antd,不久前就遇到一个很尴尬的需求:就是多张图片上传带有其它参数(注:发一次请求)antd的组件咋看咋不满足,哎,那就手撸一个吧。demo已上传到GitHub,欢迎star

一 预览

ps: 样式什么的大家不要在意

二  html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>图片上传</title>
    <link rel="stylesheet" href="css/tinyImgUpload.css">
</head>
<body>

<div id="upload">

</div>
<button class="submit">submit</button>
<script src="js/tinyImgUpload.js"></script>
<script>
document.documentElement.style.fontSize = document.documentElement.clientWidth*0.1+'px';

var options = {
    path: 'http://192.168.1.240:8090/cfAdmin/retrieval/retrievalPics.do?count=1&alarmThreshold=0.8',
    onSuccess: function (res) {
        console.log(res);
    },
    onFailure: function (res) {
        console.log(res);
    }
}

var upload = tinyImgUpload('#upload', options);
document.getElementsByClassName('submit')[0].onclick = function (e) {
    upload();
}
</script>
</body>
</html>
View Code

注意: js文件的路径,不然会报错的吆

三  js部分

本来是用Carbon生成图片的,最后发现不能复制,没办法还是用view code吧

/**
 * tinyImgUpload
 * @param ele [string] [生成组件的元素的选择器]
 * @param options [Object] [对组件设置的基本参数]
 * options具体参数如下
 * path 图片上传的地址路径 必需
 * onSuccess(res) 文件上传成功后的回调 参数为返回的文本 必需
 * onFailure(res) 文件上传失败后的回调 参数为返回的文本 必需
 * @return [function] [执行图片上传的函数]
 * 调用方法
 * tinyImgUpload('div', options)
 */
function tinyImgUpload(ele, options) {
    // 判断容器元素合理性并且添加基础元素
    var eleList = document.querySelectorAll(ele);
    if(eleList.length == 0){
        console.log('绑定的元素不存在');
        return;
    }else if(eleList.length>1){
        console.log('请绑定唯一元素');
        return;
    }else {
        eleList[0].innerHTML ='<div id="img-container" >'+
                '<div class="img-up-add  img-item"> <span class="img-add-icon">+</span> </div>'+
                '<input type="file" name="files" id="img-file-input" multiple>'+
                '</div>';
        var ele = eleList[0].querySelector('#img-container');
        ele.files = [];   // 当前上传的文件数组
    }

    // 为添加按钮绑定点击事件,设置选择图片的功能
    var addBtn = document.querySelector('.img-up-add');
    addBtn.addEventListener('click',function () {
        document.querySelector('#img-file-input').value = null;
        document.querySelector('#img-file-input').click();
        return false;
    },false)

    // 预览图片
    //处理input选择的图片
    function handleFileSelect(evt) {
        var files = evt.target.files;
        console.log(evt)
        for(var i=0, f; f=files[i];i++){
            // 过滤掉非图片类型文件
            if(!f.type.match('image.*')){
                continue;
            }
            console.log(ele)
            console.log(ele.files)
            // 过滤掉重复上传的图片
            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);
            }
        }
    }
    document.querySelector('#img-file-input').addEventListener('change', handleFileSelect, false);
    // 删除图片
    function removeImg(evt) {
        if(evt.target.className.match(/img-remove/)){
            console.log('3',ele.files);
            // 获取删除的节点的索引
            function getIndex(ele){

                if(ele && ele.nodeType && ele.nodeType == 1) {
                    var oParent = ele.parentNode;
                    var oChilds = oParent.children;
                    for(var i = 0; i < oChilds.length; i++){
                        if(oChilds[i] == ele)
                            return i;
                    }
                }else {
                    return -1;
                }
            }
            // 根据索引删除指定的文件对象
            var index = getIndex(evt.target.parentNode);
            ele.removeChild(evt.target.parentNode);
            if(index < 0){
                return;
            }else {
                ele.files.splice(index, 1);
            }
            console.log('4',ele.files);
        }
    }
    ele.addEventListener('click', removeImg, false);

    // 上传图片
    function uploadImg() {
        console.log(ele.files, '11');

        var xhr = new XMLHttpRequest();
        var formData = new FormData();
        console.log('参数',formData);
        for(var i=0, f; f=ele.files[i]; i++){
            formData.append(`img_${i+1}`, f);
        }
        console.log('1',ele.files);
        console.log('2',formData);

        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.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
        // xhr.setRequestHeader("Content-Type","multipart/form-data;charset=UTF-8");
        
        xhr.send(formData);

    }
    return uploadImg;
}
View Code

四  css 样式

#img-container {

}
#img-container:after {
    content: '.';
    display: block;
    height: 0;
    visibility: hidden;
    overflow: hidden;
    clear: both;
}
.img-item {
    position: relative;
    float: left;
    margin-right: 0.1875rem;
    margin-bottom: 0.1875rem;
    height: 2.34375rem;
     2.34375rem;
    box-sizing: border-box;
}
.img-thumb {
    border: 1px solid #000;
}
.thumb-icon {
     100%;
    height: 100%;
}
.img-up-add {
    display: table;
    border: 1px dashed #E0E0E0;
}
.img-add-icon {
    display: table-cell;
    vertical-align: middle;
    text-align: center;
}
.img-remove {
    position: absolute;
    right: -0.1875rem;
    top: -0.1875rem;
    display: block;
     0.375rem;
    height: 0.375rem;
    border-radius: 50%;
    background: #f7333d;
    color: #fff;
    text-align: center;
    text-decoration: none;
    font-size: 0.25rem;
    overflow: hidden;
    background-clip: padding-box;
}
#img-file-input {
    display: none;
}
View Code

ps: 下篇分享一下如何在react应用。

五  补一个接口的图

注:这个图是后来补的 本文的请求地址已变更,所以返回的是401

PS: 项目地址 https://github.com/ght5935/tinyImgUpload(可以下载参考一下) 

原文地址:https://www.cnblogs.com/gaoht/p/11139400.html