Skip to main content

Native File Drag & Drop原生文件拖放

Overview概述

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. 将文件拖动到web内容中是常见的,许多网站都支持。Electron additionally supports dragging files and content out from web content into the operating system's world.Electron还支持将文件和内容从web内容拖到操作系统中。

To implement this feature in your app, you need to call the webContents.startDrag(item) API in response to the ondragstart event.要在应用程序中实现此功能,需要调用webContents.startDrag(item)API以响应ondragstart事件。

Example示例

An example demonstrating how you can create a file on the fly to be dragged out of the window.演示如何动态创建文件并将其拖出窗口的示例。

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.preload.js中,使用contextBridge注入方法window.electron.startDrag(...)该方法将向主进程发送IPC消息。

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

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

Index.html

Add a draggable element to index.html, and reference your renderer script:将可拖动元素添加到index.html,并引用渲染器脚本:

<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

In renderer.js set up the renderer process to handle drag events by calling the method you added via the contextBridge above.renderer.js中,通过调用通过上面的contextBridge添加的方法,设置渲染器进程以处理拖动事件。

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

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文件)中,展开接收到的事件,其中包含指向正在拖动的文件的路径和图标:

const { app, BrowserWindow, ipcMain, nativeImage, NativeImage } = require('electron')
const path = require('path')
const fs = require('fs')
const https = require('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()
}
})

After launching the Electron application, try dragging and dropping the item from the BrowserWindow onto your desktop. 启动Electron应用程序后,尝试将项目从浏览器窗口拖放到桌面上。In this guide, the item is a Markdown file located in the root of the project:在本指南中,项目是位于项目根目录中的标记文件:

Drag and drop