Skip to main content

네이티브 파일 드래그 앤 드롭

개요

파일을 다루는 특정 종류의 애플리케이션은 운영체제의 네이티브 파일 드래그 앤 드롭 기능을 지원할 필요가 있다. 웹 콘텐츠로 파일을 드래그하는 것은 흔한 기능이며, 많은 웹사이트에서 이를 지원한다. Electron은 웹 콘텐츠에서 파일과 콘텐츠를 운영체제 환경으로 드래그하는 기능도 추가로 제공한다.

이 기능을 애플리케이션에 구현하려면, ondragstart 이벤트에 반응하여 webContents.startDrag(item) API를 호출해야 한다.

예제

윈도우 밖으로 드래그할 수 있는 파일을 즉석에서 생성하는 방법을 보여주는 예제다.

Preload.js

preload.js에서 contextBridge를 사용해 window.electron.startDrag(...) 메서드를 주입한다. 이 메서드는 메인 프로세스로 IPC 메시지를 보낸다.

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

contextBridge.exposeInMainWorld('electron', {
startDrag: (fileName) => ipcRenderer.send('ondragstart', 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 파일)에서 드래그되는 파일의 경로와 아이콘을 포함하도록 이벤트를 확장한다:

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에서 아이템을 데스크톱으로 드래그 앤 드롭해 보자. 이 가이드에서 사용된 아이템은 프로젝트 루트에 위치한 마크다운 파일이다:

드래그 앤 드롭