JavaScript 练手小技巧:拖拽事件、把图片拖拽入页面

news2024/9/24 19:23:02

HTML5 新增了拖拽事件 drag,利用它可以实现把外部文件拖拽入页面中,可以实现文件的读取,上传等等功能。

拖拽,又叫拖拉、拖动,英文为 drag

拖拽事件是 HTML5 新增的事件操作。

拖拽指的是,用户在某个对象上按下鼠标键不放,拖动它到另一个位置(另一个标签),然后释放鼠标键,将该对象放在那里。

  • 被拖拽对象:鼠标拖拽的内容,可以是标签,图片,文字等。

  • 容器:被拖拽对象存放的新位置。

拖拽的对象有好几种,包括标签节点、图片、链接、选中的文字等等。在网页中,除了标签节点默认不可以拖拉,其它(图片 <img>、超链接<a>、选中的文字)都可以直接拖拉。

为了让标签节点可拖拉,可以将该标签的 draggable属性设为true

<div class="small" draggable="true">
   可拖动区域
</div>

定义了draggable属性后,就可以给标签定义拖拽事件了。

注意:drag 事件与 mousemove 事件不相容,只能取其一。

1. 被拖拽对象相关事件

拖拽是由拖动与释放两部分组成,拖拽事件也分为:被拖拽对象的相关事件容器的相关事件

  • 被拖拽对象的相关事件

事件描述
dragstart用户开始拖动元素时触发。通常在这个事件的监听函数中,指定拖拽的数据
drag元素正在拖动时触发。拖拉过程中,在被拖拉的节点上持续触发(相隔几百毫秒)
dragend用户完成元素拖动后触发。不管拖拉是否跨窗口,或者中途被取消,dragend事件总是会触发的。

下面的例子展示,如何动态改变被拖拽节点的背景色。

<div id="box" class="box" draggable="true">
</div>
<script>
    let box = document.getElementById("box");
    box.addEventListener("dragstart",function (e) {
        e.target.classList.add("dragging");
    });
    box.addEventListener("dragend",function (e) {
        e.target.classList.remove("dragging");
    });
</script>

 

div#box 被拖动的时候,会变成黄色背景。拖拽结束的时候,又变回红色背景。

2. 容器相关事件

  • 容器相关事件

事件描述
dragenter当被鼠标拖动的对象进入其容器范围内时触发此事件。通常应该在这个事件的监听函数中,指定是否允许在当前节点放下(drop)拖拉的数据。如果当前节点没有该事件的监听函数,或者监听函数不执行任何操作,就意味着不允许在当前节点放下数据。在视觉上显示拖拉进入当前节点,也是在这个事件的监听函数中设置。
dragover当被拖动的对象在另一对象容器范围内拖动时触发此事件。dragenter事件在进入该节点时触发,然后只要没有离开这个节点,dragover事件会持续触发
dragleave当被鼠标拖动的对象离开其容器范围时触发此事件
drop被拖拉的节点或选中的文本,松开鼠标释放到容器节点时,在容器节点上触发。 注意,如果当前节点不允许drop,或者用户按下 ESC 键,取消这个操作,不会触发该事件。 该事件的监听函数负责取出拖拉数据,并进行相关处理

 注意:

  • 默认情况下,浏览器阻止任何东西向HTML元素放置拖拽的发生。

  • 要在容器(可放置区域)设置阻止默认事件 event.preventDefault(),否则 drop 事件不会被触发。

  • 一般阻止默认事件是写在 dragoverdrop 事件上。

下面的例子展示,如何实现将一个节点从当前父节点,拖拉到另一个父节点中。

<div class="dropzone">
    <div id="box" class="box" draggable="true">
        要拖动的div
    </div>
</div>

<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<script>
    let box = document.getElementById("box");
    let dropzone = document.querySelectorAll(".dropzone");
    box.addEventListener("dragstart",function (e) {
        let _box = this;
        // 开始拖拽的时候,让原来的 div 隐藏,要通过延迟代码执行。
        setTimeout(function () {
            _box.style.opacity = 0;
        },0);
    });
    box.addEventListener("dragend",function (e) {
        // 结束拖拽,原来的div恢复显示。
        e.target.style.opacity = 1;
    });

    dropzone.forEach(function (item,index) {
        item.addEventListener("dragenter",function (e) {
            e.target.classList.add("over");
        });
        item.addEventListener("dragover",function (e) {
            // 阻止默认事件
            e.preventDefault();
        }); 
        item.addEventListener("dragleave",function (e) {
            e.target.classList.remove("over");
        });
        item.addEventListener("drop",function (e) {
            e.preventDefault();  // 阻止默认事件
            // 把 div.box放入对应的div.dropzone 中
            e.target.appendChild(box);
        });
    });
</script>

3. drag 事件执行顺序

  1. dragstart (被拖拽元素)

  2. dragenter(容器)

  3. dragover (容器)

  4. dragleave(容器)

  5. drop (容器)

  6. dragend (被拖拽元素)

dragstart 开始,到 dragend 为止,整个过程都在连续触发 drag (被拖拽元素)。如下图所示,仅保留 dragstart、drag、dragend 事件。

 

 4. 案例:拖拽图片文件到页面中

(1)准备

拖拽文件到页面 div.box 标签中。样式自定。

 <div class="box" id="box">
        <span>把文件拖放在这里</span>
    </div>

 

必须给 dragover 添加禁止默认事件代码。

box.addEventListener("dragover",function (e) {
    e.preventDefault();
});

(2)DataTransfer.files

event.dataTransfer.files属性是一个 FileList 对象,包含一组本地文件,可以用来在拖拉操作中传送。如果本次拖拉不涉及文件,则该属性为空的 FileList 对象。

可以遍历 FileList,也可以利用索引获取某个 file ,并获取filename,type,size 等属性。

let box = document.getElementById("box");
box.addEventListener("dragover",function (e) {
    e.preventDefault();
});
box.addEventListener("drop",function (e) {
    e.preventDefault();
    let file = e.dataTransfer.files[0];
    console.info( e.dataTransfer.files )
    console.info( file )
    console.info( file.name )
    console.info( file.type )
    console.info( file.size )
});

可以利用 URL.createObjectURL(file) 静态方法获取 file 的路径。

(3)拖拽单张图片到页面中

box.addEventListener("drop",function (e) {
    e.preventDefault();
    box.innerHTML = "";
    // 获取文件
    let file = e.dataTransfer.files[0];
    // 获取文件 type
    console.info( file.type );
    // 判断文件是否是图片
    if( /image/.test(file.type)){
        console.info("图片");
    }else{
        box.innerHTML = "请拖入一个图片文件,如png,jpg或者gif";
        return false; // 终止函数运行
    }
    // 生成文件路径
    let url = URL.createObjectURL(file);
    // 创建一个 img 标签
    let img = document.createElement("img");
    img.src = url;
    // 把 img 添加到 box 里。
    box.appendChild(img) 
});

 

(4)拖拽多张图片到页面中

box.addEventListener("drop",function (e) {
    e.preventDefault();
    box.innerHTML = "";
    // 获取文件列表
    let files = e.dataTransfer.files;
    [...files].forEach(function (item,index) {
        // 判断文件是否是图片
        if( /image/.test(item.type)){
            console.info("图片");
            // 生成文件路径
            let url = URL.createObjectURL(item);
            // 创建一个 img 标签
            let img = document.createElement("img");
            img.src = url;
            // 把 img 添加到 box 里。
            box.appendChild(img)
        }else{
            console.info(`文件${index}不是图片`);
        }
    });
});

 

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

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

相关文章

【Rust】4. Rust 基础

4. Rust 基础 4.1 变量和可变性 4.1.1 常量 const xxx: type ...&#xff1a;常量使用 const 来定义&#xff0c;且必须注明值的类型常量在声明它的作用域之中&#xff0c;常量在整个程序生命周期中都有效 4.1.2 隐藏&#xff08;Shadowing&#xff09; 隐藏&#xff08;Sh…

基于卡尔曼滤波器的PID控制-1

采用M语言对算例进行仿真&#xff01;&#xff01;设置控制对象传递函数&#xff1a;取采样时间为1ms&#xff0c;采用Z变换将对象离散化&#xff0c;并描述为离散状态方程的形式&#xff1a;x(k 1) Ax(k) B(u(k)wk))y(k) Cx(k)带有测量噪声的被控对象输出为&#xff1a;yv(k)C…

Ubuntu18.04下安装OpenCV4.2.0与Opencv_contrib(图文详细报错总结)

Ubuntu18.04下安装OpenCV4.2.0与Opencv_contrib&#xff08;图文详细&#xff09;前期准备—环境依赖Cmake&#xff08;编译器&#xff09;依赖环境Python环境streamer环境图像处理依赖安装OpenCV编译OpenCV配置cmake编译参数make编译配置OpenCV动态库验证OpenCV环境# python环…

724. 寻找数组的中心下标——你行吗???

兄弟们&#xff0c;今早遇到了一个题&#xff0c;案例看起来很简单&#xff0c;于是就尝试起来&#xff0c;求知己&#x1f62d;题目描述724. 寻找数组的中心下标难度简单511收藏分享切换为英文接收动态反馈给你一个整数数组 nums &#xff0c;请计算数组的 中心下标 。数组 中…

一文了解 Java 中 so 文件的加载原理

前言 无论是 Android 开发者还是 Java 工程师应该都有使用过 JNI 开发&#xff0c;但对于 JVM 如何加载 so、Android 系统如何加载 so&#xff0c;可能鲜有时间了解。 本文通过代码、流程解释&#xff0c;带大家快速了解其加载原理&#xff0c;扫清困惑。 1. System#load() …

3.1.2 访问控制符及修饰符

文章目录1.访问控制符2.静态字段/方法/代码块2.1 静态字段2.2 静态常量2.3 静态方法2.4 特点2.5 static入门案例2.6 静态的调用关系2.7 静态代码块2.7.1 格式2.7.2 特性&#xff1a;2.7.3 执行顺序2.7.4 案例练习3.final的概念3.1 特点3.2 final入门案例1.访问控制符 在JAVA中…

【HBase——陌陌海量存储案例】8. 基于Phoenix消息数据查询(下)

索引示例二&#xff1a;创建本地索引 需求 在程序中&#xff0c;我们可能会根据订单ID、订单状态、支付金额、支付方式、用户ID来查询订单。所以&#xff0c;我们需要在这些列上来查询订单。 针对这种场景&#xff0c;我们可以使用本地索引来提高查询效率。 创建本地索引 cre…

超全小程序开发的学习 知识点

第一章&#xff1a;邂逅小程序开发 01_小程序开发和各个平台小程序的介绍 小程序加载的时候是双线程模型.wxml文件和wxss文件是一个线程&#xff0c;js和json文件是一个线程。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mEP3PUoo-1675132790458…

七步让您的MySQL服务器更安全

本文将以最常见的数据库管理系统——MySQL为例&#xff0c;向您介绍如何通过7步骤来安全加固数据库服务器。 不知您是否发现一种现象&#xff0c;那些初学渗透测试的人员往往过于关注应用的安全性&#xff0c;而对数据库的安全性不太重视。他们殊不知&#xff0c;没有数据库的…

上海亚商投顾:兔年首日开门红 北向资金净流入超186亿

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。市场情绪两市早盘受外围影响大幅高开&#xff0c;随后指数高开低走&#xff0c;板块及个股相对活跃&#xff0c;汽车产业链&a…

视频图像分析处理流程(完整版)

来源&#xff1a;投稿 作者&#xff1a;LSC 编辑&#xff1a;学姐 一、视频分析处理的完整流程 (1)视频编解码的入门知识 尽管压缩工具五花八门&#xff0c;但是他们的目的都只有一个&#xff1a;都是为了减小文件的占用空间。 除去我们常见的.zip&#xff0c;.7z&#xff0…

MyBatis框架如何实现数据查询?有几种方法?

在实际开发中&#xff0c;查询操作通常都会涉及到单条数据的精确查询&#xff0c;以及多条数据的模糊查询。那么使用MyBatis框架是如何进行这两种查询的呢&#xff1f;接下来&#xff0c;本小节将讲解下如何使用MyBatis框架根据客户编号查询客户信息&#xff0c;以及根据客户名…

【前沿技术】在安全且可靠的区块链基础设施中运行业务条线应用

发表时间&#xff1a;2022年4月27日 信息来源&#xff1a;coingeek.com 了解特定企业的业务需求将使你能够构建出一个可扩容的业务条线应用&#xff0c;它将按照你想要的方式进行运作&#xff0c;并在不可篡改的BSV区块链中保存相关记录。 大多数企业都有一个业务条线&#xf…

《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(1)-HTTP和HTTPS基础知识

1.简介 有的小伙伴或者童鞋们可能会好奇地问&#xff0c;不是讲解和分享抓包工具了怎么这里开始讲解HTTP和HTTPS协议了。这是因为你对HTTP协议越了解&#xff0c;你就能越掌握Fiddler的使用方法&#xff0c;反过来你越使用Fiddler&#xff0c;就越能帮助你了解HTTP协议。 Fid…

HashMap原理分析

HashMap原理分析JDK7 HashMap1、模型介绍2、底层实现原理3、描述一下put的过程4、HashMap扩容机制&#xff1a;5、HashMap中的循环链表是如何产生的6、HashMap和HashTable的区别7、HashMap为什么用红黑树而不用B树&#xff1f;JDK8 HashMapJDK7 HashMap 1、模型介绍 HashMap在…

18. time和calendar模块

当代码中需要使用到时间时&#xff0c;我们通常会使用time模块来获取当前时间或者时间戳。 时间戳&#xff1a;从1970年1月1日&#xff08;UTC/GMT的午夜&#xff09;开始所经过的秒数&#xff0c;不考虑闰秒。 1. 时间戳 获取当前时间戳&#xff1a; import timeprint(time…

Springboot+vue预约上门维修服务系统

前端技术&#xff1a;nodejsvueelementui一般是采用前后端分离模式&#xff0c; 后端支持python/php/java/nodejs MTV模式 M:model&#xff0c;模型&#xff0c;负责与数据库交互 V:view&#xff0c;视图是核心&#xff0c;负责接收请求、获取数据、返回结果 T:template&…

并发编程学习(八):ReentrantLock特性、哲学家吃饭问题

ReentrantLock 是java.util.concurrent.locks包下的类。相对于synchronized,它具备如下特性&#xff1a;可中断。可以设置超时时间。可以设置公平锁。支持多个条件变量。即可以有个多个waitset等待队列。与synchronized都支持可重入。ReentrantLock的基本语法&#xff1a;// 获…

c++11 标准模板(STL)(std::multiset)(二)

定义于头文件 <set>template< class Key, class Compare std::less<Key>, class Allocator std::allocator<Key> > class multiset;(1)namespace pmr { template <class Key, class Compare std::less<Key>> using…

Day12【元宇宙的实践构想01】—— 元宇宙概念和发展历程

&#x1f483;&#x1f3fc; 本人简介&#xff1a;男 &#x1f476;&#x1f3fc; 年龄&#xff1a;18 ✍每日一句&#xff1a;【道固远&#xff0c;笃行可至&#xff1b;事虽巨&#xff0c;坚为必成】 &#x1f6a9; 今日留言&#xff1a;亮亮被迫去练科目二啦&#xff0c;定时…