跳转到主内容

原生文件拖 & 放

概览

作为桌面程序,当然希望能够实现操作系统的 drag & drop 功能。 很多网站已经支持拖拽文件, Electron 当然也支持

To implement this feature in your app, you need to call the webContents.startDrag(item) API in response to the ondragstart event.

示例

一个演示如何动态创建要从窗口中拖出的文件的示例。

Preload.js

In preload.js use the contextBridge to inject a method window.electron.startDrag(...) that will send an IPC message to the main process.

const { contextBridge, ipcRenderer } = require('electron')
const path = require('node:path')

contextBridge.exposeInMainWorld('electron', {
startDrag: (fileName) => {
ipcRenderer.send('ondragstart', path.join(process.cwd(), fileName))
}
})

Index.html

添加一个可拖动元素到 index.html, 并引用你的渲染器脚本:

<div style="border:2px solid black;border-radius:3px;padding:5px;display:inline-block" draggable="true" id="drag">拖动我</div>
<script src="renderer.js"></script>

Renderer.js

In renderer.js set up the renderer process to handle drag events by calling the method you added via the contextBridge above.

document.getElementById('drag').ondragstart = (event) => {
event.preventDefault()
window.electron.startDrag('drag-and-drop.md')
}

Main.js

在主进程中(main.js 文件),将收到的事件带上文件路径和图标扩展到正在拖动的文件:

const { app, BrowserWindow, ipcMain } = require('electron/main')
const path = require('node:path')
const fs = require('node:fs')
const https = require('node:https')

function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})

win.loadFile('index.html')
}

const iconName = path.join(__dirname, 'iconForDragAndDrop.png')
const icon = fs.createWriteStream(iconName)

// Create a new file to copy - you can also copy existing files.
fs.writeFileSync(path.join(__dirname, 'drag-and-drop-1.md'), '# First file to test drag and drop')
fs.writeFileSync(path.join(__dirname, 'drag-and-drop-2.md'), '# Second file to test drag and drop')

https.get('https://img.icons8.com/ios/452/drag-and-drop.png', (response) => {
response.pipe(icon)
})

app.whenReady().then(createWindow)

ipcMain.on('ondragstart', (event, filePath) => {
event.sender.startDrag({
file: path.join(__dirname, filePath),
icon: iconName
})
})

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})

app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

启动 Electron 应用程序后,尝试将该项从 BrowserWindow 拖放到桌面上。 在本指南中,本项是位于项目根目录下的 Markdown 文件:

拖放