在Electron中简单实现拖拽功能
背景
实现简单的拖拽文件、图片到系统本地,拖拽消息体文本发送(类似于微信、QQ中的功能)
实现拖拽到本地系统,不考虑实现方式,使用中的配合的
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 处理逻辑
的一些问题:
因为是直接使用提供的能力,所以这里会覆盖的 事件,如设置的数据会被覆盖
如果需要监听事件,需要在 后通知到子进程,表示拖拽操作已结束
定制比较简陋,不能像那样默认使用渲染半透明图
在 系统中一次只能拖动一个文件
鼠标光标手势是个加号图标,等同于
、 中 位置有差异,分别在左右两边
HTML5 Drag and Drop
判断存在本地文件路径时,使用,否则默认执行的操作
// render.js
const filePath = getFilePathSync()
if(filePath) {
//阻止默认操作
event.preventDefault()
// 发送IPC
await ipcRenderer.invoke('drag-start')
/* 这里可以处理dragend事件逻辑 */
return
} else {
// html5 draggable处理
}
draggable介绍
的的事件触发分为 和 两部分
拖拽区域
触发顺序: > (持续触发) >
在元素中绑定事件监听
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);
}
}
整体拖拽 && 局部文本选区拖拽
在目标元素的父元素上,设置,并且监听目标元素的事件,当进入目前元素区域时,取消父元素的,离开目标元素区域,恢复父元素的

// 查找父元素
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}`)
释放区域
目标元素作为释放区域绑定事件监听

/*子组件*/
注意事项:
触发顺序: -> (持续,每100多毫秒重新计算触发) -> ->
通常会有一些进入释放区域和离开释放区域的状态变化,可以放到 和 中处理;和 会包含子子元素的触发响应,需要判断针对对应区域真实的事件,可以考虑增加栈存储对应的区域进出,如为空,则表示离开了当前区域。
拖拽操作默认是可以触发自动向上、向下鼠标滚动行为(在获取的情况下)
小结
的拖拽操作,大部分还是可以考虑使用web实现方式;本地文件(存在本地路径),可以使用拖拽到本地系统
我是废材壶,前端开发者,欢迎微信搜一搜「 CodeLife集」阅读不迷路
