原生文件拖放
🌐 Native File Drag & Drop
概述
🌐 Overview
某些类型的应用在操作文件时可能希望支持操作系统本地的文件拖放功能。将文件拖入网页内容很常见,并且许多网站都支持这种操作。Electron 还支持将文件和内容从网页内容中拖出到操作系统环境中。
🌐 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.
要在你的应用中实现此功能,你需要在响应 ondragstart 事件时调用 webContents.startDrag(item) API。
🌐 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')
contextBridge.exposeInMainWorld('electron', {
startDrag: (fileName) => ipcRenderer.send('ondragstart', 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:
