ネイティブファイルのドラッグ&ドロップ
概要
ファイルを操作する特定の種類のアプリケーションは、オペレーティングシステムのネイティブファイルのドラッグ&ドロップ機能をサポートしたい場合があります。ファイルをWebコンテンツにドラッグすることは一般的であり、多くのWebサイトでサポートされています。Electronは、Webコンテンツからオペレーティングシステムの世界にファイルとコンテンツをドラッグアウトすることもサポートしています。
アプリケーションにこの機能を実装するには、 `ondragstart` イベントに応答して `webContents.startDrag(item)` APIを呼び出す必要があります。
例
ウィンドウからドラッグアウトされるファイルをその場で作成する方法を示す例。
Preload.js
`preload.js` では、 `contextBridge` を使用して、メインプロセスにIPCメッセージを送信するメソッド `window.electron.startDrag(...)` を挿入します。
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">Drag me</div>
<script src="renderer.js"></script>
Renderer.js
`renderer.js` では、上記の `contextBridge` で追加したメソッドを呼び出すことによって、ドラッグイベントを処理するようにレンダラープロセスを設定します。
document.getElementById('drag').ondragstart = (event) => {
event.preventDefault()
window.electron.startDrag('drag-and-drop.md')
}
Main.js
メインプロセス( `main.js` ファイル)で、受信したイベントを、ドラッグされているファイルへのパスとアイコンで拡張します。
- 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ファイルです。