在Electron中简单实现拖拽功能
2021/11/7 6:14:05
本文主要是介绍在Electron中简单实现拖拽功能,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
背景
实现简单的拖拽文件、图片到系统本地,拖拽消息体文本发送(类似于微信、QQ中的功能)
实现拖拽到本地系统,不考虑mouse
实现方式,使用Electron
中的startdrag
配合Browser
的Drag and Drop
startdrag
Electron
API (startDrag) 提供拖拽文件到桌面系统本地的能力
使用情况比较简单,主进程监听事件,调用startdrag
// main-process ipcMain.on('drag-start', (event) => { event.sender.startdrag({ file: 'drag-start.md', // string | string[] icon:'icon.png' }) return true })
子进程IPC通信主进程,
// render.js await ipcRenderer.invoke('drag-start') // dragend 处理逻辑
startdrag
的一些问题:
-
因为
startDrag
是直接使用V8
提供的能力,所以这里会覆盖html5
的draggable
事件,如event.dataTransfer.setData()
设置的数据会被覆盖 -
如果需要监听
dragend
事件,需要在event.sender.startdrag
后通知到子进程,表示拖拽操作已结束 -
icon
定制比较简陋,不能像html5 draggable
那样默认使用DOM
渲染半透明图 -
startdrag
在Window
系统中一次只能拖动一个文件 -
鼠标光标手势是个加号图标,等同于
event.dataTransfer.effectAllowed = 'move'
-
window
、mac
中icon
位置有差异,分别在左右两边
HTML5 Drag and Drop
判断存在本地文件路径时,使用startdrag
,否则默认执行html5
的draggable
操作
// render.js const filePath = getFilePathSync() if(filePath) { //阻止默认操作 event.preventDefault() // 发送IPC await ipcRenderer.invoke('drag-start') /* 这里可以处理dragend事件逻辑 */ return } else { // html5 draggable处理 }
draggable介绍
htm5
的draggable
的事件触发分为drag
和 drop
两部分
拖拽目标 | 事件触发 |
---|---|
drag | 一个可拖拽项被拖拽着的时候,一直触发,直到拖拽结束 |
dragstart | 开始拖拽项目 先于drag 触发 |
dragend | 拖拽操作结束 |
释放目标 | 事件触发 |
---|---|
dragenter | 拖拽元素进入可释放区域时触发此事件 |
dragleave | 拖拽元素离开释放区域时触发此事件 |
dragover | 拖拽元素拖拽到一个区域中,持续触发此事件 (100多毫秒触发一次) |
drop | 在释放区域上释放拖拽操作,触发此事件 |
拖拽区域
触发顺序: dragstart
> drag
(持续触发) > dragend
在元素中绑定dragstart
事件监听
const el = document.querySelector('#target') el.addEventListener('dragstart',(e:DragEvent) => {})
自定义拖拽图像
// 生成拖拽图像 function applyDragImage(event: DragEvent,class:string, label:string | null):void { const dragImage = document.createElement('div') dragImage.className = class; dragImage.textContent = label; if(event.dataTransfer) { document.body.appendChild(dragImage); event.dataTransfer.setDragImage(dragImage, -10, -10); setTimeout(() => document.body.removeChild(dragImage), 0); } }
整体拖拽 && 局部文本选区拖拽
在目标元素的父元素上,设置draggable=true
,并且监听目标元素的mouseenter/mouseleave
事件,当进入目前元素区域时,取消父元素的draggable=false
,离开目标元素区域,恢复父元素的draggable=true
// 查找父元素 const parent = document.querySelector('#targetParent'); parent.draggable=true const el = document.querySelector('#target') // 进入目标元素区域 el.addEventListener('mouseenter', (e:DragEvent) => { parent.removeAttribute('draggable') parent.ondragstart = null },true) // 离开目标元素区域 el.addEventListener('mouseleave', (e:DragEvent) => { parent.draggable = true })
拖拽图片到系统本地
const TYPE = 'image/png' const NAME = 'name.png' const URL = 'https://example.com/img/1.png' // Chrome支持的非标准属性 event.dataTransfer.setData('DownloadURL', `${TYPE}:${NAME}:${URL}`)
释放区域
目标元素作为释放区域绑定事件监听
<template> <div @dragenter="handleDragEnterFn @dragleave="handleDragLeaveFn" @dragover.prevent @drop="handleDropFn"> /*子组件*/ </div> </template> <script lang="ts"> data() { return { dropStack: new Set() } } handleDragEnterFn(e:DragEvent) { this.dropStack.add(e.target) } handleDragLeaveFn(e:DragEvent) { this.dropStack.delete(e.target) // 栈为空,真正的离开当前区域 if(!this.dropStack.size) { } } handleDropFn(e:DragEvent) { } </script>
注意事项:
- 触发顺序:
dragenter
->dragover
(持续,每100多毫秒重新计算触发) ->dragleave
->drop
- 通常会有一些进入释放区域和离开释放区域的状态变化,可以放到
dragenter
和dragleave
中处理;dragenter
和dragleave
会包含子子元素的触发响应,需要判断针对对应区域真实的dragleave
事件,可以考虑增加dropStack
栈存储对应的区域进出,如为空,则表示离开了当前区域。 - 拖拽操作默认是可以触发自动向上、向下鼠标滚动行为(在获取
focus()
的情况下)document.querySelector('#dropTarget').focus()
小结
Electron
的拖拽操作,大部分还是可以考虑使用web实现方式;本地文件(存在本地路径),可以使用startdrag
拖拽到本地系统
我是废材壶,前端开发者,欢迎微信搜一搜「 CodeLife集」阅读不迷路
参考
- Fixing drag and drop in Electron | Fileside
- ‘DownloadURL’ for drag and drop - Web Platform News
- Native File Drag & Drop | Electron (electronjs.org)
这篇关于在Electron中简单实现拖拽功能的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15PingCAP 黄东旭参与 CCF 秀湖会议,共探开源教育未来
- 2024-05-13PingCAP 戴涛:构建面向未来的金融核心系统
- 2024-05-09flutter3.x_macos桌面os实战
- 2024-05-09Rust中的并发性:Sync 和 Send Traits
- 2024-05-08使用Ollama和OpenWebUI在CPU上玩转Meta Llama3-8B
- 2024-05-08完工标准(DoD)与验收条件(AC)究竟有什么不同?
- 2024-05-084万 star 的 NocoDB 在 sealos 上一键起,轻松把数据库编程智能表格
- 2024-05-08Mac 版Stable Diffusion WebUI的安装
- 2024-05-08解锁CodeGeeX智能问答中3项独有的隐藏技能
- 2024-05-08RAG算法优化+新增代码仓库支持,CodeGeeX的@repo功能效果提升