原生js实现拖拽上传(拖拽时高亮上传区域)

news2024/11/29 2:39:21

文章目录

  • drop相关事件说明-MDN
  • 演示
  • 代码(.html)

drop相关事件说明-MDN

演示

在这里插入图片描述

代码(.html)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Drag Upload</title>
  <style>
    html,
    body {
      height: 100%;
      width: 100%;
    }

    .drag-upload-box {
      width: 200px;
      height: 130px;
      border-radius: 6px;
      border: 2px dashed #ccc;
      overflow: hidden;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
    }

    .drag-upload-box.guide {
      border-color: orange;
    }

    .drag-upload-box.available {
      border-color: green;
    }

    .drag-upload-box > * {
      /* 防止拖拽到 子元素导致触发 dragleave*/
      pointer-events: none;
    }

    .drag-upload-box .empty {
      color: #ccc;
    }

    .drag-upload-box .file-name:empty + .empty {
      display: unset;
    }

    .drag-upload-box .file-name + .empty {
      display: none;
    }

    .input-file {
      display: none;
    }

    .obstacle {
      width: 100%;
      height: 200px;
      background: #ccc;
    }
  </style>
</head>

<body>
  <div id="root">
    <div id="upload" class="drag-upload-box">
      <input id="file" class="input-file" type="file">
      <span class="file-name"></span>
      <span class="tips empty">点击/拖拽到此处上传文件</span>
    </div>
    <div class="obstacle no1">
      其他元素
    </div>
  </div>

</body>
<script>
  const $ = selector => document.querySelector(selector)
  const addEvent = (element, event, handler) => element.addEventListener(event, handler)

  // 文件上传input
  const fileInput = $('#file')
  // 拖放区域
  const dragBox = $('#upload')
  const fileName = dragBox.querySelector('.file-name')
  const tips = dragBox.querySelector('.tips')

  // 两个标识;来判断当前鼠标是否在上传文件/body中。
  let inUploadBox = false
  let inBody = false

  // 绑定拖拽事件
  addEvent(dragBox, 'dragenter', handlerEvents)
  addEvent(dragBox, 'dragover', handlerEvents)
  addEvent(dragBox, 'dragleave', handlerEvents)
  addEvent(dragBox, 'drop', handlerEvents)
  // 点击上传
  addEvent(dragBox, 'click', (e) => {
    fileInput.click()
  })
  // 选择文件回调
  addEvent(fileInput, 'change', () => {
    getFile(fileInput.files[0])
  })

  const light = {
    guide() {
      this.classList.add('guide')
      this.classList.remove('available')
      tips.innerText = '拖拽到此处'
      inUploadBox = false
    },
    available() {
      this.classList.add('available')
      this.classList.remove('guide')
      tips.innerText = '松开鼠标'
      inUploadBox = true
    },
    clearLight() {
      this.removeClass('guide', 'available')
      tips.innerText = '点击/拖拽到此处上传文件'
      inUploadBox = false
    },
    removeClass() {
      this.classList.remove(...arguments)
      return this
    }
  }
  Object.assign(dragBox, light)

  function handlerEvents(e) {
    // 阻止事件传播触发 body 的dragover
    e.stopPropagation()
    e.preventDefault()
    // 禁用dragover默认事件,否则会在浏览器中打开文件
    switch (e.type) {
      // 进入拖放区域
      case 'dragenter':
        dragBox.available()
        break

      // 离开拖放区域
      case 'dragleave':
        if (inBody) {
          dragBox.guide()
        } else {
          dragBox.clearLight()
        }
        break

      // 在拖拽区域内松开鼠标(拖放完成/放入文件)
      case 'drop':
        getFile(e.dataTransfer.files[0])
        dragBox.clearLight()
        inBody = false
        break
      default:
        break
    }
  }

  // 获取到文件
  function getFile(file) {
    console.log(file)
    if (!file) {
      fileName.innerText = ''
      return
    }
    const fileSize = (file.size / (1024 * 1024)).toFixed(2) + 'MB'
    fileName.innerText = file.name + ' ' + fileSize
    // TODO: 上传、预览
  }

  /* 以上是正常拖拽上传部分,下面代码处理拖拽到body后的指引/处理 */
  const body = document.body
  addEvent(body, 'dragenter', handlerOutEvents)
  addEvent(body, 'dragover', handlerOutEvents)
  addEvent(body, 'dragleave', handlerOutEvents)
  addEvent(body, 'drop', handlerOutEvents)

  function handlerOutEvents(e) {
    e.stopPropagation()
    e.preventDefault()

    switch (e.type) {
      case 'dragenter':
        // 拖拽到 body && 未到上传文件区域;高亮指引到上传区域
        dragBox.guide()
        inBody = true
        break
      case 'dragover':
        break
      case 'dragleave':
        if (inUploadBox) {
          dragBox.removeClass('guide')
        }
        break
      case 'drop':
        dragBox.clearLight()
        inBody = false
        break
      default:
        break
    }
  }
</script>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2227368.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

最新XL换脸术!EcomID,更像更强,结合InstantID和PuLID优点,200万训练集,6.6显存占用,ComfyUI

由阿里妈妈最新开源的换脸工具&#xff1a;EcomID&#xff0c;结合了InstantID和PuLID优点&#xff0c;以获得更好的背景一致性、面部关键点控制、更真实的面部以及更高的相似度。旨在从单个ID参考图像生成定制的保ID图像&#xff0c;优势在于很强的语义一致性&#xff0c;同时…

情感咨询小程序的市场需求大吗?

情感咨询小程序的市场需求较大&#xff0c;主要体现在以下几个方面&#xff1a; 情感问题普遍存在5&#xff1a; 恋爱关系困扰&#xff1a;在恋爱过程中&#xff0c;人们经常会遇到诸如沟通不畅、争吵频繁、信任危机等问题。例如&#xff0c;年轻人在恋爱初期可能会因为不了解…

技术分享 | 大语言模型增强灰盒模糊测试技术探索

大语言模型凭借其庞大的参数规模&#xff0c;能够通过无监督学习从海量文本中获取知识&#xff0c;从而不仅能够深刻理解文本语义&#xff0c;还能准确识别文本的格式和结构。凭借对不同数据结构的深度理解&#xff0c;大语言模型已在众多领域得到广泛应用。其中&#xff0c;尤…

Cmake Error:could not find any instance of Visual Studio.

出现以下错误 解决方案&#xff1a; 安装visual stuido 2017。 检查是否安装“使用C的桌面开发” 检查是否安装了扩展开发 点开“单个组件”是否安装了以下组件 编辑计算机环境变量&#xff0c;

linux查看文件命令

查看文件命令 显示命令 cat 语法&#xff1a;cat 【选项】 文件 选项 命令含义n显示行号包括空行b显示行号不包括空行s压缩空行为一行A显示隐藏字符 cat -n 文件&#xff1a;显示行号包括空行 cat -b 文件 cat -s 文件 cat -A 文件 more和less是 分页查看 tac和rev都…

使用Python统计目录下所有.txt文件中的字符数

前言 在日常开发或数据处理中&#xff0c;我们经常需要对大量文本文件进行各种统计操作&#xff0c;比如计算总字数。本文将介绍一种简单的方法&#xff0c;通过Python脚本遍历指定目录下的所有.txt文件&#xff0c;并统计这些文件中的字符总数。这个过程可以帮助开发者更好地…

【Kaggle | Pandas】练习2:索引,选择和分配

文章目录 数据总表1、读取列2、读取某列的第几行的值3、第一行数据4、读取列中前10个值5、读取索引标签为1 、 2 、 3 、 5和8的记录6、包含索引标签为0 、1 、10和100的记录的country 、province 、 region_1和region_2列7、 前 100 条记录的country和variety列8、包含Italy葡…

三款计算服务器配置→如何选择科学计算服务器?

科学计算在众多领域都扮演着关键角色&#xff0c;无论是基础科学研究还是实际工程应用&#xff0c;强大的计算能力都是不可或缺的。而选择一台合适的科学计算服务器&#xff0c;对于确保科研和工作的顺利进行至关重要。 首先&#xff0c;明确自身需求是重中之重。要仔细考虑计算…

【ceral】c++轻量的序列化库

背景 在开发硬件产品时&#xff0c;会有一些参数配置文件&#xff0c;为了保密性或者传输&#xff0c;需要对其序列化处理&#xff0c;待到产品读取文件时&#xff0c;进行反序列化解码转化为设定的参数类型。 简介 ceral是一个仅包含头文件的C序列化库&#xff0c;可以将任…

前后端请求、返回数据的多种方式

Springboot项目的业务逻辑 &#x1f319;项目基本结构&#xff1a; 通常情况下&#xff0c;我们在搭建后端项目的时候&#xff0c;处理业务逻辑我们需要用到Controller,Service,Mapper(mybatis,mybatis-plus)&#xff0c;Entry各层之间的相互调用来完成&#xff0c;还有就是我…

计算机网络-MSTP的基础概念

前面我们大致了解了MSTP的由来&#xff0c;是为了解决STP/RSTP只有一根生成树导致的VLAN流量负载分担与次优路径问题&#xff0c;了解MSTP采用实例映射VLAN的方式实现多实例生成树&#xff0c;MSTP有很多的理论概念需要知道&#xff0c;其实与其它的知识一样理论复杂配置还好的…

php伪协议和move_uploaded_file、rename、copy等文件操作

move_uploaded_file、rename、copy 三个函数的区别&#xff1a; move_uploaded_file 函数是专门用于将通过 HTTP 上传的临时文件移动到指定位置的。如果你想要将一个已经存在的文件移动到另一个位置&#xff0c;而不是上传的文件&#xff0c;那么你应该使用 rename 函数或 co…

Lucas带你手撕机器学习——套索回归

好的&#xff0c;下面我将详细介绍套索回归的背景、理论基础、实现细节以及在实践中的应用&#xff0c;同时还会讨论其优缺点和一些常见问题。 套索回归&#xff08;Lasso Regression&#xff09; 1. 背景与动机 在机器学习和统计学中&#xff0c;模型的复杂性通常会影响其在…

完全透彻了解一个asp.net core MVC项目模板1

当我们使用Visual Studio 2022去新建一个基于asp.net core Web项目的时候&#xff0c;一般有三种选择&#xff0c;一种是空项目&#xff0c;一种是基于MVC的项目、再有一种就是基于包含Razor Pages实例的web应用。如下图&#xff1a; 今天&#xff0c;我们打算选择基于MVC模…

【无标题】2024年第五届 MathorCup 数学应用挑战赛——大数据竞赛赛题

2024年第五届 MathorCup 数学应用挑战赛——大数据竞赛赛题已发布~&#xff0c;本届初赛时间为&#xff1a;2024年10月25日18:00至2024年11月1日20:00。本次赛题分为A&#xff0c;B两道&#xff0c;所有参赛队从赛道 A、B 中任选一题作答。在报名系统内选择自己队伍的赛道时&am…

离散化算法简介

【离散化简介】 ★ 离散化是一种数据处理的技巧&#xff0c;本质上可以看成是一种“哈希”&#xff0c;其保证数据在哈希以后仍然保持原来的“全/偏序”关系。用来离散化的可以是大整数、浮点数、字符串等等。★ 离散化的本质&#xff0c;是映射。原理是将间隔很大的元素&#…

毫米波技术基础

什么是毫米波&#xff1f; 顾名思义&#xff0c;毫米波是波长 (λ) 约为 1 毫米&#xff08;更准确地说是 1 至 10 毫米&#xff09;的电磁波。使用方程式f c /λ 将该波长转换为频率&#xff0c;其中c是光速 (3 x 10 8 m/s)&#xff0c;得出 30-300 GHz 的频率范围。国际电信…

【STM32】内存管理

首先问个问题&#xff0c;你知道如何在LCD上显示SD卡文件浏览&#xff1f;-----需要读取所有文件名到内存&#xff0c;然后才能显示到LCD上。 一般的方法&#xff1a;是定义一个数组来存储文件名 1&#xff1a;需要知道最大文件名的长度 2&#xff1a;需要知道文件的个数。1…

OpenCV图像处理方法:腐蚀操作

腐蚀操作 前提 图像数据为二值的&#xff08;黑/白&#xff09; 作用 去掉图片中字上的毛刺 显示图片 读取一个图像文件&#xff0c;并在一个窗口中显示它。用户可以查看这个图像&#xff0c;直到按下任意键&#xff0c;然后程序会关闭显示图像的窗口 # cv2是OpenCV库的P…

使用Python中的jieba库进行简单情感分析

在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;情感分析是一项重要的任务&#xff0c;它可以帮助我们理解文本背后的情感倾向。本文将通过一个简单的例子来介绍如何使用Python的jieba库对中文文本进行基本的情感分析。 1. 环境准备 首先&#xff0c;确保已经安装…