Рендеринг BrowserWindow в приложении Electron



Мне нужна помощь экспертов по JavaScript в отношении приложения, которое я создаю с помощью Electron. Суть проблемы в том, что если я уйду с основной страницы (index.html) и вернусь к ней на короткое время, но очень заметно, отобразятся элементы div и ul, составляющие вертикальную меню с вкладками, которое находится в левой части страницы (см. рисунки ниже).

Мы с коллегой не можем понять и не можем найти адекватную информацию в Интернете, как исправить или отрегулируйте это. Один знакомый нам человек предложил создать своего рода средство визуализации для поддержки различных оконных потоков, созданных в Main.js, но он не знал, как это сделать, и мы не нашли информации о том, как это сделать. Это правильный путь?

Или это просто случай неправильного размещения или отсутствия кода, который каждый раз мешает правильной загрузке страницы?

Или что-то еще вместе? Любая помощь будет принята с благодарностью, так как я прижат к стене при решении этой проблемы. Заранее спасибо!

Индекс.html рендеринг:

введите здесь описание изображения

Index.html пост-рендеринг:

введите здесь описание изображения


Main.js:

const electron = require('electron');
// Module to control application life.
const {app} = electron;
// Module to create native browser window.
const {BrowserWindow} = electron;
var express = require('express');
var expressapp = express();

var hostname = 'localhost';
var port = 3000;

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win;

function createWindow() {
// Create the browser window.
win = new BrowserWindow({
width: 1920,
height: 1080,
webPreferences: {
  nodeIntegration: true,
  resizable: true,
  fullscreenable: true,
  maximizable: true,
  minamizable: true,
  movable: true,
  autoHideMenuBar: false,
  allowDisplayingInsecureContent: true,
  allowRunningInsecureContent: true
  }
  })


  // and load the index.html of the app.
  win.loadURL(`file://${__dirname}/index.html`);

  // Open the DevTools.
  win.webContents.openDevTools();

// Emitted when the window is closed.
win.on('closed', () => {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
win = null;
});
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);

// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit();
}
});

app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (win === null) {
createWindow();
}
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

expressapp.use(express.static(__dirname + '/public'));

expressapp.listen(port, hostname, function() {
console.log(`Server running at http://${hostname}:${port}`);
});


Index.html код:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
  <link rel="stylesheet" type:"text/css" href="css/jquery-ui.min.css">
  <link rel="stylesheet" type:"text/css" href="css/bootstrap.min.css">
  <link rel="stylesheet" type:"text/css" href="css/jquery.scrollbar.css">
  <link rel="stylesheet" type:"text/css" href="css/tabs.css">
  <link rel="stylesheet" type:"text/css" href="css/persian-datepicker-0.4.5.min.css">
  <link rel="stylesheet" type:"text/css" href="css/clockpicker.css">
  <link rel="stylesheet" type:"text/css" href="styles.css">
  <link rel="stylesheet" type:"text/css" href="css/entry.css">
  <link rel="stylesheet" type:"text/css" href="css/navbar.css">
  <link rel="stylesheet" type:"text/css" href="css/modal.css">
  <meta id="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
...
<form name="mainForm">
  <div id="sections">
      <ul>
        <li><a href="#section1">Section 1</a></li>
        <li><a href="#section2">Section 2</a></li>
        <li><a href="#section3">Section 3</a></li>
        <li><a href="#section4">Section 4</a></li>
        <li><a href="#section5">Section 5</a></li>
        <li><a href="#section6">Section 6</a></li>
        <li><a href="#section7">Section 7</a></li>
        <li><a href="#section8">Section 8</a></li>
        <li><a href="#section9">Section 9</a></li>
        <li><a href="#section10">Section 10</a></li>
        <li><a href="#section11">Section 11</a></li>
      </ul>
...
  <script>
      window.jQuery = window.$ = require('jquery');
  </script>
  <script src="js/jquery-ui.js"></script>
  <script src="js/bootstrap.min.js"></script>
  <script src="js/jquery.scrollbar.min.js"></script>
  <script src="js/persian-date.min.js"></script>
  <script src="js/persian-datepicker-0.4.5.min.js"></script>
  <script src="js/clockpicker.js"></script>
  <script src="js/jqwidgets/jqxcore.js"></script>
  <script src="js/jqwidgets/jqxexpander.js"></script>
  <script src="js/jqwidgets/jqxinput.js"></script>
  <script src="js/jqwidgets/jqxpasswordinput.js"></script>
  <script src="js/jqwidgets/jqxbuttons.js"></script>
  <script src="js/jqwidgets/jqxvalidator.js"></script>
  <script src="js/data.js"></script>
  <script src="js/model.js"></script>
  <script src="js/view.js"></script>
  <script src="js/form-init.js">
  </script>
</form>
</body>
</html>


Изменен код окна браузера:

let win;

function createWindow() {
// Create the browser window.
win = new BrowserWindow({
show: false,
width: 1920,
height: 1080,
backgroundColor: '#4d6b9e',
webPreferences: {
nodeIntegration: true,
resizable: true,
fullscreenable: true,
maximizable: true,
minamizable: true,
movable: true,
autoHideMenuBar: false,
allowDisplayingInsecureContent: true,
allowRunningInsecureContent: true
}
})

win.loadURL(`file://${__dirname}/index.html`);

// and load the index.html of the app.
win.once('ready-to-show', () => {
win.show()
})

person Steven Kanberg    schedule 22.09.2016    source источник


Ответы (2)


Я не могу точно сказать, что происходит, по вашим скриншотам и описанию, но пробовали ли вы установить цвет фона для окна браузера?

Кроме того, с моей стороны было бы упущением не упомянуть, что запуск экспресс-сервера внутри приложения Electron, как правило, является плохой идеей, если ваше приложение не предназначено только для работы на машине с воздушным зазором.

person Vadim Macagon    schedule 22.09.2016
comment
Спасибо за комментарий, @Vadim. Я ценю внимание. Во-первых, возможно, я плохо описал проблему. По сути, второй рисунок - это то, как страница должна выглядеть при первом входе. Первое изображение - это то, что вы видите на короткое время (~ 1 сек), когда входите. Маркированный неупорядоченный список, лежащий в основе среды с вкладками, отображается, когда этого не следует делать. К сожалению, изменение цвета фона не помогло. Во-вторых, я не слышал об использовании экспресс-сервера в Electron. Это почему? До вашего комментария я ничего не видел в Интернете о том, что он не используется. - person Steven Kanberg; 23.09.2016
comment
@Steve Похоже, у вас есть некоторые элементы, которые визуализируются без стилей, и вскоре после этого применяется стиль. Попробуйте создать скрытое окно браузера, а затем сделать его видимым, когда оно запускает _ 1_. - person Vadim Macagon; 23.09.2016
comment
@Steve Что касается _1 _... Если вы используете express сервер в приложении / локально, это означает, что все ваши ресурсы доступны локально, Electron может загружать .html документы и все связанные ресурсы прямо с диска, так в чем смысл раскручивания HTTP-сервер? Кроме того, когда пользователь открывает удаленный веб-сайт в своем браузере, JavaScript на этом веб-сайте может получить доступ к HTTP-серверу, запущенному на компьютере пользователя, прочтите Эксплойт Trend Micro. - person Vadim Macagon; 23.09.2016
comment
Я пробовал скрыть / показать окно браузера, как вы указали, но это не повлияло. Я бы подумал, что сначала он отобразит все окно, но при загрузке заметной разницы не было. Измененный код размещен ниже. Мысли? - person Steven Kanberg; 28.09.2016

В приведенном здесь примере кода показано, что вы запускаете свой сервер Express как часть основного процесса Electron:

var express = require('express');
var expressapp = express();

Судя по тому, что я читал, это плохая практика, поскольку это означает, что любые операции, которые должен выполнять ваш сервер Express, на мгновение приостановят ваш поток основного процесса Electron, пока они обслуживаются. Это не имеет никакого значения, когда вы выполняете небольшие загрузки файлов, но что-либо существенное будет мешать главному процессу Electron управлять его обычными задачами (обновлять электронный фрейм, меню и т. Д. - оболочку приложения, которая окружает область отображения браузера), пока он обрабатывает любая работа, связанная с сервером Express (который вы создали и теперь выполняет внутри основного процесса Electron).

Более полное объяснение этой проблемы можно найти по адресу: https://blog.axosoft.com/2016/03/04/electron-things-to-know/

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

person Kim Gentes    schedule 27.02.2017