原生js实现一个简单的拖拽文件上传功能

195 阅读1分钟

一、使用原生js实现一个简易版本的拖拽文件上传功能

<!DOCTYPE html>
<html lang="en"><head>
    <meta charset="UTF-8">
    <title>显示选择图片的缩略图</title>
    <style>
        :root {
            --upload-width: 500px;
            --upload-height: 300px;
            --primary-color: #409eff;
            --upload-dragger-horizontal: 50px;
            --upload-dragger-vertical: 10px;
        }
​
        * {
            border: 0;
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
​
​
​
        .upload {
            width: var(--upload-width);
            height: var(--upload-height);
            cursor: pointer;
        }
​
        .upload .upload-dragger {
            width: 100%;
            height: 100%;
            padding: var(--upload-dragger-horizontal) var(--upload-dragger-vertical);
            border-radius: 8px;
            border: 1.5px dashed #ccc;
            transition: border-color .4s, background .4s;
        }
​
        .upload .upload-dragger:hover {
            border-color: var(--primary-color);
        }
    </style>
</head><body>
    <div id="app">
        <div class="upload-wrapper">
            <!-- 上传input -->
            <div class="upload">
                <div class="upload-dragger">
                    <div class="text">点击或将单个/多个图片拖放到此处</div>
                    <i class="icon"></i>
                </div>
                <input type="file" style="display: none">
            </div>
            <!-- 上传后的附件列表 -->
            <div class="upload-list">
​
            </div>
        </div>
    </div>
​
​
    <script>
        (function (global, factory) {
            if (typeof exprots === 'object' && typeof module !== 'undefined') {
                factory(exports)
            }
            else if (typeof define === 'function' && define.amd) {
                define(['exports'], factory)
            }
            else {
                global = typeof globalThis !== 'undefined' ? globalThis : global || self;
                factory(global.Upload = {});
            }
        })(this, (function (exports) {
            'use strict';
​
            let fileList = reactiveHW([]);
​
            const wrapper = document.querySelector(".upload-wrapper");
            const dropbox = wrapper.children[0];
            const uploadList = wrapper.children[1];
            let dropboxDragger = null;
            let input = null;
            if (dropbox) {
                dropboxDragger = dropbox.children[0];
                input = dropbox.children[1];
                dropbox.addEventListener("dragenter", dragenter, false);
                dropbox.addEventListener("dragover", dragover, false);
                dropbox.addEventListener("dragleave", dragleave, false);
                dropbox.addEventListener("drop", drop, false);
​
                dropboxDragger.addEventListener("click", () => {
                    input.click();
                })
​
                input.addEventListener("change", readFile);
            }
​
            function eventInit (e) {
                e.stopPropagation();
                e.preventDefault();
            }
​
​
            // 目标进入drop区域
            function dragenter (e) {
                e.stopPropagation();
                e.preventDefault();
                dropbox.style.background = '#ecf5ff';
                dropboxDragger.style.borderWidth = '2px';
                dropboxDragger.style.borderColor = '#409eff';
            }
​
            // 目标位于drop区域上方
            function dragover (e) {
                eventInit(e);
            }
​
            // 目标离开drop区域
            function dragleave (e) {
                eventInit(e);
​
                dropbox.style.background = '#fbfbfb';
                dropboxDragger.style.borderWidth = '1px';
                dropboxDragger.style.borderColor = '';
            }
​
            // 目标在drop区域被释放/放置(松开鼠标)
            function drop (e) {
                eventInit(e);
​
                dropbox.style.background = '#fbfbfb';
                dropboxDragger.style.borderWidth = '1px';
                dropboxDragger.style.borderColor = '';
                var dt = e.dataTransfer;
                var files = dt.files;
                handleFiles(files);
            }
​
            // 点击上传文件后的方法
            function readFile (e) {
                handleFiles(e.target.files);
            }
​
            // 数组
            function update (target, prop) {
                // target发生变化数据, 哪一个索引发生了变化
                if (prop == "length") return;
​
                const divE = document.createElement('div');
                divE.innerHTML = target[prop].name;
                uploadList.append(divE);
            }
​
            function handleFiles (files) {
                fileList.push(files[0]);
                // 这里写上传文件的方法
            }
​
            function reactiveHW (target) {
                return new Proxy(target, {
                    get (target, prop) {
                        return target[prop];
                    },
                    set (target, prop, val) {
                        target[prop] = val;
                        update(target, prop);
                        return target[prop];
                    }
                });
            }
​
            const keys = {
                readFile,
                handleFiles,
                drop,
                dragleave,
                dragover,
                dragenter
            }
​
            for (let key in keys) {
                const item = keys[key];
                exports[key] = item;
            }
​
            Object.defineProperty(exports, '__esModule', { value: true });
        }))
    </script>
​
    <script>
​
​
​
    </script>
</body></html>