一杯茶的功夫,了解前端图片上传原理

214 阅读1分钟

一、实现效果与思路

1.1、实现效果

1.1.1、未上传图片时

upload-初始化.png

1.1.2、上传图片时

upload-上传图片.png

1.2、样式解析

有一个上传文件的框,当上传的数量到5个后,上传文件的框会被挤到下一行,所以我们有理由相信整个是一个div,这个div宽度固定,flex-wrap: wrap; html, css代码如下:

    <html>
        <head>
            <style>
                .upload-file-component-box {
                    width: 550px;
                    max-width: 550px;
                    display: flex;
                    flex-wrap: wrap;
                    box-sizing: border-box;
                }
                .upload-file-component {
                    width: 100px;
                    height: 100px;
                    box-sizing: border-box;
                    background-color: #fafafa;
                    border: 1px dashed #d9d9d9;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                }
                input {
                    display: none;
                }
            </style>
        </head>
        <body>
            <!-- 整个组件 -->
            <div class = 'upload-file-component-box'>
                <input class="input" type="file">
                <!-- 上传组件的灰色框 -->
                <div class="upload-file-component">
                    <span>
                        <svg viewBox="64 64 896 896" focusable="false" data-icon="plus" width="1em" height="1em" fill="currentColor" aria-hidden="true"><defs><style></style></defs><path d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"></path><path d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"></path></svg>
                    </span>
                </div>
            </div>
        </body>
    </html>

1.3、功能分析

其实一句话就可以总结:点击upload-file-component元素就相当于点击input元素,并使用FileReader对象读取当前上传的文件并展示; 详细的过程可以这么来说:

  • input标签的type=file时,可以上传文件,上传文件时会触发input标签的onchange事件
  • 在onchange事件里,我们可以通过默认参数event来拿到上传的file对象
  • 光拿到file对象是不够的,我们还需要将图片展示出来,这个时候H5对象fileReader闪亮登场
  • 当我们new一个fileReader时(const p1 = new FileReader()),p1此时就具备了一个读取方法一个读取完成事件
  • 回到onchange方法里,我们通过event.target.files拿到上传的所有的文件对象,遍历这些对象,每次遍历,我们都调用 p1.readAsDataUrl 方法来读取文件,参数是当前遍历的file
  • 读取完成后,会自动触发p1.onload事件,在这个事件里,我们通过默认参数可以拿到当前图片的base64编码
  • 最后,动态创建img元素,并将base64编码赋值给src即可完成图片的展示

具体js代码如下:

    <html>
        <body>
            <div class="upload-file-component-box">
                <input onchange="inputChange(event)" class="input" type="file">
                <div class="upload-file-component" onclick="uploadFile()">
            </div>
            <script>
                let currentFileType = 0;
                // 加载图片
                function loadImage (event){
                    const img = document.createElement('img');
                    img.src = event.currentTarget.result;
                    img.style.width = '100px';
                    img.style.height = '100px';
                    img.style.marginRight = '10px';
                    img.style.marginBottom = '10px';
                    document.querySelector('.upload-file-component-box').insertBefore(img, document.querySelector('.upload-file-component'));
                };
                // 上传文件事件
                function inputChange (event){
                    const filelist = event.target.files;
                    const filereader = new FileReader();

                    filereader.onload = function (fileresult){
                        loadImage(fileresult);
                    };
            
                    for (let file of filelist){
                        currentReadFile = file;
                        if (file.type.indexOf('image') >= 0){
                            // 图片的读取方式
                            currentFileType = 1;
                            filereader.readAsDataURL(file);
                        }
                    }
        
                };
            </script>
        </body>
    </html>

二、最后

在阅读过程中,欢迎各位看官纠错并指正,如果有遗漏的地方也欢迎指出~~~