1

I've got the following problem: I want to access the css properties of styles.css inside Electron. The problem is that I can't use document.getElementsByClassName() because there is no document in Node. The desired behaviour is to change the color of one div once the q key is pressed. This is my code:

index.js

const url = require('url');
const path = require('path');

const {app, BrowserWindow, globalShortcut} = require('electron');
let mainWindow;

app.on('ready', function(){
    // Create new window
    mainWindow = new BrowserWindow({backgroundColor: '#000000', fullscreen : true, frame : false});
    // Load html in window
    mainWindow.loadURL(url.format({
      pathname: path.join(__dirname, 'index.html'),
      protocol: 'file:',
      slashes:true
    }))
    globalShortcut.register('Esc', () => {
        app.quit();
    });
    globalShortcut.register('q', () => {
      leftLight();
  });

});


//This doesn't work
function leftLight() {
  var element =   ;
  element.style["background-color"] = "yellow";
}

index.html

<!DOCTYPE html>
<html lang="en">
<meta name="viewport" content="width=device-width, initial-scale=1">

<head>
    <link rel="stylesheet" href="styles.css">
    <title>Document</title>
</head>
<body>
    <div class = rect_green> <h2 class=blocktext >LEFT FENCER</h2></div>
    <div class = rect_red><h2 class=blocktext> RIGHT FENCER</h2> </div>
    <div class = crono> <h2 class=blocktext>3:00</h2></div>
</body>
</html>

styles.css

.rect_green {
  display: flex;
  align-items: center;
  height: 400px;
  width:60%;
  background-color: green;
  position:relative;
  top:100px;
  text-align: center;

}

.rect_red {
  display: flex;
  align-items: center;
  height:400px;
  width:60%;
  background-color: red;
  position:relative;
  top:120px;
  float:right;
}

.crono {
  display: flex;
  align-items: center;
  height:300px;
  width:40%;
  background-color: beige;
  position:fixed;
  left: 50%;
  bottom : 50px;
  transform: translate(-50%, 0px);
  margin: 0 auto;
}

.blocktext {
  margin-left: auto;
  margin-right: auto;
  font-family: "Palatino", Times, serif;
  font-size: 180px;
}

Edit

After the modifications suggested by Gr8Miller (still no communication): index.html

<!DOCTYPE html>
<html lang="en">
<meta name="viewport" content="width=device-width, initial-scale=1">

<head>
    <link rel="stylesheet" href="styles.css">
    <title>Document</title>
</head>
<body>
    <div class = rect_green> <h2 class=blocktext >LEFT FENCER</h2></div>
    <div class = rect_red><h2 class=blocktext> RIGHT FENCER</h2> </div>
    <div class = crono> <h2 class=blocktext>3:00</h2></div>
</body>

<script type="text/javascript">
        var ipc = require('electron').ipcRenderer;
        ipc.on('key-pressed-q', (e) => {
            //var element =  document.getElementsByClassName("rect_green");
            //element.style["background-color"] = "yellow";
            console.log("q pressed in html file");    
        });
    </script>

</html>

And index.js

const url = require('url');
const path = require('path');

const {app, BrowserWindow, globalShortcut, ipcMain, webContents} = require('electron');
let mainWindow;

app.on('ready', function(){
    // Create new window
    mainWindow = new BrowserWindow({
      backgroundColor: '#000000',
      fullscreen : true, 
      frame : false,
      icon : __dirname + "/res/icon.jpg",
      webPreferences: {
        nodeIntegration : true
      }
    });
    // Load html in window
    mainWindow.loadURL(url.format({
      pathname: path.join(__dirname, 'index.html'),
      protocol: 'file:',
      slashes:true
    }))
    globalShortcut.register('Esc', () => {
        app.quit();
    });
    globalShortcut.register('q', () => {
      leftLight();

  });

});

function leftLight() {
  mainWindow && mainWindow.webContents.send('key-pressed-q');
  console.log("Sending q pressed to html...");
}
customcommander
  • 17,580
  • 5
  • 58
  • 84
Norhther
  • 545
  • 3
  • 15
  • 35

3 Answers3

0

Possible duplicate of this.

Try to create another js file containing your code and load it as a script from your html document.

Add this to your index.html:

<script type="text/javascript" charset="utf8" src="./pageScript.js"></script>

And create a separate pageScript.js file with the code you want:

window.onload = function () {
    // your code here
    function leftLight() {
        var element = ;
        element.style["background-color"] = "yellow";
    }

    // Also don't forget to call the function
    leftLight();
}
Wang Liang
  • 4,244
  • 6
  • 22
  • 45
mliakos
  • 373
  • 2
  • 9
0

View related tasks should be handled in render process but not main process.

in Electron, the entry js(index.js in your case) runs in main process (it acts manager of all browser windows it creates) and the browser window itself runs in render process. html elements and imported/embedded js "live"/"run" in browser windows(in render process), so document can only be directly accessed in render process.

in your case. the style change task should be done in render process:

  1. send a message(e.g. key-pressed-q) to render process from the main process on key q is pressed:
  2. change the style in render process on receiving message (key-pressed-q):

index.js

    mainWindow = new BrowserWindow({
        backgroundColor: '#000000', 
        fullscreen : true, 
        frame : false, 
        webPreferences: {
            nodeIntegration: true
        }});
    ...
    function leftLight() {
        mainWindow && mainWindow.webContents.send('key-pressed-q');
    }

index.html

    ...
    <script type="text/javascript">
    var ipc = require('electron').ipcRenderer;
    ipc.on('key-pressed-q', (e) => {
        console.log(e);
        var element =   ;
        element.style.backgroundColor = "yellow";
    });
    </script>
    ...

Added in 2019-11-18

There are other errors need to be fixed in your code which is not related to electron but just html basics:

//var element =  document.getElementsByClassName("rect_green");
//element.style["background-color"] = "yellow";

getElementsByClassName returns an array of Element(Array<Element>) but not a single Element. element.style doesn't have a field named background-color, it should be backgroundColor.

the console.log in the render process won't print logs in the main process's console, it outputs to its hosting browser window's own console. if you want to check the log, you have to open the browser window's Devtools first.

  // in your `index.js`

  // Open the DevTools.
  mainWindow.webContents.openDevTools(); // `console.log` in `index.html` output to its hosting browser window's own console.
  // in your `index.html`

var ipc = require('electron').ipcRenderer;
ipc.on('key-pressed-q', (e) => {
  var element = document.querySelector(".rect_green");
  element.style.backgroundColor = "yellow";
  console.log("q pressed in html file");   // this won't output to the main process's console.
});

Miller
  • 33
  • 4
  • Using this gives me no communication between the render and main process. I added some logs to be sure, and it seems that it sends but it doesn't receive in the channel in the html file. – Norhther Nov 17 '19 at 15:54
  • @Norhther is there any error? maybe you need to enable nodeIntegration manually, I modified my reponse – Miller Nov 17 '19 at 16:04
  • @Norhther can you tell me how did you check if `index.html` receives the message or not? there are some other errors according to your pasted code. – Miller Nov 18 '19 at 15:53
0

Change your index.html to this :

<!DOCTYPE html>
<html lang="en">
<meta name="viewport" content="width=device-width, initial-scale=1">

<head>
    <link rel="stylesheet" href="styles.css">
    <title>Document</title>
</head>
<body>
    <div class = rect_green> <h2 class=blocktext >LEFT FENCER</h2></div>
    <div class = rect_red><h2 class=blocktext> RIGHT FENCER</h2> </div>
    <div class = crono> <h2 class=blocktext>3:00</h2></div>
    <script>
      function leftLight() {
        const element = document.getElementsByClassName("yourclassname")
        element[0].style.color = "red"
      }
      window.onkeydown = function(e) {
        if (e.key == "q") {
          leftLight()
        }
      }
    </script>
</body>
</html>
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 28 '22 at 12:53