其他分享
首页 > 其他分享> > 在Electron中简单实现拖拽功能

在Electron中简单实现拖拽功能

作者:互联网

背景

实现简单的拖拽文件、图片到系统本地,拖拽消息体文本发送(类似于微信、QQ中的功能)

实现拖拽到本地系统,不考虑mouse实现方式,使用Electron中的startdrag配合BrowserDrag 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的一些问题:

HTML5 Drag and Drop

判断存在本地文件路径时,使用startdrag,否则默认执行html5draggable操作

// render.js
const filePath = getFilePathSync()
if(filePath) {
    //阻止默认操作
    event.preventDefault()
    // 发送IPC
    await ipcRenderer.invoke('drag-start')
    /* 这里可以处理dragend事件逻辑 */
    return
} else {
// html5 draggable处理
}

draggable介绍

htm5draggable的事件触发分为dragdrop 两部分

拖拽目标事件触发
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
image.png

  // 查找父元素
   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}`)

释放区域

目标元素作为释放区域绑定事件监听

image.png

    <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>
    
    

注意事项:

小结

Electron的拖拽操作,大部分还是可以考虑使用web实现方式;本地文件(存在本地路径),可以使用startdrag拖拽到本地系统

我是废材壶,前端开发者,欢迎微信搜一搜「 CodeLife集」阅读不迷路

weix.png

参考

标签:触发,元素,drag,拖拽,draggable,Electron,简单,event
来源: https://blog.csdn.net/weixin_40494579/article/details/121186627