Кнопки сворачивания и закрытия не работают в приложении Electron

#javascript #node.js #electron #window

Вопрос:

Я создаю приложение с использованием электронной платформы и попытался использовать кнопки, чтобы закрыть и свернуть окно. Я перепробовал множество способов сделать это, но безуспешно.

Вот что у меня есть на данный момент:
HTML:

 <body>
    <!-- Titlebar -->
    <button id="minimize-button">-</button>
    <button id="close-button">x</button>

    <!-- Script -->
    <script src="./js/minimize-close.js"></script>
</body>
 

JS (minimize-close.js):

 const { ipcRenderer } = require('electron');

document.getElementById("minimize-button").addEventListener('click', () => {
    ipcRenderer.send('minimize-window');
});

document.getElementById("close-button").addEventListener('click', () => {
    ipcRenderer.send('close-window');
});
 

JS (index.js):

 const { app, BrowserWindow, ipcMain } = require('electron');

function createWindow(){
    const window = new BrowserWindow({
        width: 960, height: 580,
        resizable: false, maximizable: false,
        frame: false, autoHideMenuBar: true,
        icon: './icon.ico',
        webPreferences: {
            nodeIntegration: true,
            devTools: false
        }
    });

    window.loadFile('./src/index.html');
}

// Minimize and close window
ipcMain.on('minimize-window', () => {
    window.minimize();
});

ipcMain.on('close-window', () => {
    window.close();
});

app.whenReady().then(() => {
    createWindow();

    app.on('activate', function(){
        if(BrowserWindow.getAllWindows().length === 0){
            createWindow();
        }
    });
});

app.on('window-all-closed', function(){
    if(process.platform !== 'darwin'){
        app.quit();
    }
});
 

Комментарии:

1. Ваш пульт кажется неправильным, я считаю , что так и должно быть const { remote } = require("electron") , потому что вам просто нужен электрон, а не удаленный модуль. Кроме того, похоже, что remote устарел, и вместо этого вам следует использовать ipcMain и ipcRenderer ( electronjs.org/docs/api/ipc-main ), который позволит вам отправлять события от клиента в основной процесс.

2. Я уже пробовал использовать ipcRenderer, я попробую еще раз.

3. Можете ли вы добавить свою попытку с ipcRenderer и ipcMain в свой вопрос, пожалуйста?

4. Я сделаю это, если не получится.

5. Подождите, я думаю, у вас может возникнуть проблема с областью действия window переменной, вы определяете переменную window в области действия функции createWindow , но используете переменную за пределами этой области. Попробуйте установить ipcMain.on s внутри createWindow функции и посмотрите, работает ли это

Ответ №1:

Вам нужно установить contextIsolation: false .
Также я читал, что window это должно быть глобальным. Если нет, то в какой-то момент он будет собран сборщиком мусора, потому что функция, которая его создала, уже завершена.

 let window;

function createWindow(){
    window = new BrowserWindow({
        width: 960, height: 580,
        resizable: false, maximizable: false,
        frame: false, autoHideMenuBar: true,
        icon: './icon.ico',
        webPreferences: {
            nodeIntegration: true,
            // devTools: false,  // commented for debugging purposes
            contextIsolation: false
        }
    });

    window.loadFile('./src/index.html');
    window.webContents.openDevTools(); // Open dev tools to see if any error arised. In this case I saw 'require is not defined' before setting contextIsolation. Remove it when going into production.
}
 

Вариант Б: более «безопасный»

Если безопасность вызывает беспокойство, и вы хотите nodeIntegration и contextIsolation хотите сохранить их безопасные значения по умолчанию, то preload.js необходима схема.
Это должно иметь место, если удаленное содержимое загружается вашим приложением.

HTML

 <body>
    <!-- Titlebar -->
    <button id="minimize-button">-</button>
    <button id="close-button">x</button>
</body>
 

preload.js

 const { ipcRenderer } = require('electron');

window.addEventListener('DOMContentLoaded', () => {
    document.getElementById("minimize-button").addEventListener('click', () => {
        ipcRenderer.send('minimize-window');
    });
    
    document.getElementById("close-button").addEventListener('click', () => {
        ipcRenderer.send('close-window');
    });
})
 

index.js

 const path = require('path');


function createWindow(){
    window = new BrowserWindow({
        width: 960, height: 580,
        resizable: false, maximizable: false,
        frame: false, autoHideMenuBar: true,
        icon: './icon.ico',
        webPreferences: {
            // devTools: false,  // commented for debugging purposes
            preload: path.join(__dirname, 'preload.js')
        }
    });

    window.loadFile('./src/index.html');
    window.webContents.openDevTools(); // Open dev tools to see if any error arised. In this case I saw 'require is not defined' before setting contextIsolation. Remove it when going into production.
}