原生文件拖放
¥Native File Drag & Drop
概述
¥Overview
某些类型的操作文件的应用可能希望支持操作系统的原生文件拖放功能。将文件拖到 Web 内容中很常见,并且许多网站都支持。Electron 还支持将文件和内容从 Web 内容拖到操作系统的世界中。
¥Certain kinds of applications that manipulate files might want to support the operating system's native file drag & drop feature. Dragging files into web content is common and supported by many websites. Electron additionally supports dragging files and content out from web content into the operating system's world.
要在你的应用中实现此功能,你需要调用 webContents.startDrag(item)
API 来响应 ondragstart
事件。
¥To implement this feature in your app, you need to call the
webContents.startDrag(item)
API in response to the ondragstart
event.
示例
¥Example
该示例演示了如何动态创建要拖出窗口的文件。
¥An example demonstrating how you can create a file on the fly to be dragged out of the window.
Preload.js
在 preload.js
中,使用 contextBridge
注入方法 window.electron.startDrag(...)
,该方法将向主进程发送 IPC 消息。
¥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
,并引用你的渲染器脚本:
¥Add a draggable element to index.html
, and reference your renderer script:
<div style="border:2px solid black;border-radius:3px;padding:5px;display:inline-block" draggable="true" id="drag">Drag me</div>
<script src="renderer.js"></script>
Renderer.js
在 renderer.js
中,通过调用你通过上面的 contextBridge
添加的方法来设置渲染器进程来处理拖动事件。
¥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
文件)中,使用正在拖动的文件的路径和图标展开接收到的事件:
¥In the Main process (main.js
file), expand the received event with a path to the file that is
being dragged and an icon:
- main.js
- preload.js
- index.html
- renderer.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()
}
})
const { contextBridge, ipcRenderer } = require('electron/renderer')
contextBridge.exposeInMainWorld('electron', {
startDrag: (fileName) => ipcRenderer.send('ondragstart', fileName)
})
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>Drag the boxes below to somewhere in your OS (Finder/Explorer, Desktop, etc.) to copy an example markdown file.</p>
<div style="border:2px solid black;border-radius:3px;padding:5px;display:inline-block" draggable="true" id="drag1">Drag me - File 1</div>
<div style="border:2px solid black;border-radius:3px;padding:5px;display:inline-block" draggable="true" id="drag2">Drag me - File 2</div>
<script src="renderer.js"></script>
</body>
</html>
document.getElementById('drag1').ondragstart = (event) => {
event.preventDefault()
window.electron.startDrag('drag-and-drop-1.md')
}
document.getElementById('drag2').ondragstart = (event) => {
event.preventDefault()
window.electron.startDrag('drag-and-drop-2.md')
}
启动 Electron 应用后,尝试将项目从 BrowserWindow 拖放到桌面上。在本指南中,该项目是位于项目根目录中的 Markdown 文件:
¥After launching the Electron application, try dragging and dropping the item from the BrowserWindow onto your desktop. In this guide, the item is a Markdown file located in the root of the project: