Utilizing Node and Electron to dynamically adjust CSS style properties

Having a dilemma here: I need to access the CSS properties from styles.css within Electron. Trying to use

document.getElementsByClassName()
won't work because Node doesn't have document. The goal is to change the color of a specific div when the q key is pressed. Below is the code snippet:

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

Following some changes suggested by Gr8Miller (yet still no luck): 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...");
}

Answer №1

Similar question can be found at this link.

To resolve this issue, consider creating a new JavaScript file with your code and then load it as a script in your HTML document.

You can add the following line to your index.html:

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

Next, create a separate pageScript.js file where you can include your code like this:

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

    // Make sure to call the function
    leftLight();
}

Answer №2

Handling of view related tasks in Electron:

When working with Electron, it's important to understand that the entry JavaScript file (such as index.js) runs in the main process, acting as the manager for all browser windows it creates. The browser window itself runs in the render process where HTML elements and imported/embedded JavaScript code are executed. This means that the document object can only be directly accessed in the render process.

In scenarios like yours, where style changes need to be applied dynamically, it is best practice to perform these tasks in the render process:

  1. Send a message (e.g. key-pressed-q) from the main process to the render process when a specific key (like q) is pressed:
  2. Update the style in the render process upon receiving the 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 = document.querySelector(".rect_green");
        element.style.backgroundColor = "yellow";
    });
    </script>
    ...

Updated on 2019-11-18

Aside from Electron-specific considerations, there are also other errors in your code related to basic HTML principles:

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

The function getElementsByClassName returns an array of Elements, not a single Element. Additionally, the correct property for setting background color is backgroundColor, not background-color.

Furthermore, keep in mind that the console.log statements in the render process will not output logs to the main process's console. To view these logs, you'll need to open the DevTools of the browser window hosting the render process.

  // in your `index.js`

  // Open the DevTools.
  mainWindow.webContents.openDevTools(); // `console.log` in `index.html` will be shown in its 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 log won't appear in the main process's console.
});

Answer №3

Revise your index.html with the following changes :

<!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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Get selectize.js to display only options that begin with the user's input

Using selectize.js, my current setup looks like this: Instead of only showing words that start with 'arm', it displays words or options containing 'arm' as a substring elsewhere. I want to modify the function to display only words or ...

Issue with ASP.NET ConfirmButtonExtender Missing Background in Internet Explorer

Recently, I noticed an issue with the ConfirmButtonExtender on a Cancel button. It was working perfectly fine in Firefox with a semi-transparent background and a simple modal popup. But when I tested it on IE, it showed a generic JavaScript-style alert box ...

Error: Node.js Selenium Unexpected Identifier - Syntax Issue

I recently wrote a script: var webdriver = require('selenium-webdriver'); var driver = new webdriver.Builder().forBrowser('firefox').build(); driver.get('https://www.youtube.com/?hl=lt&gl=LT'); JavascriptExecutor js = (Ja ...

Encountering 'undefined' issue with find operation in mongoDB

Seeking assistance to utilize all available values in my code. bericht.find({ room: room }).toArray(function(err, docs) { assert.equal(err, null); str2 = str2 + docs.message; The function I'm using can successfully loca ...

Inability to update Vue.js component data even after a successful GET request

I am encountering an issue with a component that initially contains a default object, and then fetches a populated object via a GET request upon creation. Despite successfully updating this.profile within the method, the changes do not seem to propagate ...

Configuring the Port for NodeJS Express App on Heroku

Currently, I am in the process of hosting my website on Heroku and configuring everything to ensure my app is up and running smoothly. However, each time I attempt to submit the form, undefined errors occur. For more details on the Undefined Errors and Co ...

What is the proper way to implement parameters and dependency injection within a service?

My objective is to achieve the following: (function(){angular.module('app').factory("loadDataForStep",ls); ls.$inject = ['$scope','stepIndex'] function ls ($scope, stepIndex) { if ($routeParams ...

AngularJS: Monitoring $locationChangeStart for token verification

I am attempting to check if the next has a token or not, but it is not working and I am getting an error: TypeError: Cannot read property 'next' of undefined Any suggestions? app.js .run(function ($rootScope, $location,$log,User) { ...

Utilize both a model and a boolean variable within expressionProperties in Formly configuration

I'm having trouble setting formly form fields to disabled based on model properties and a boolean variable. The code snippet I've tried doesn't seem to be working as expected. expressionProperties: { 'templateOptions.disabled' ...

CSS: Concealing a separate div

I am working with a parent div in my code that has 2 child divs. I am hoping to find a way to hide the second child when hovering over the first child, using only CSS or JavaScript. Take a look at my Fiddle here <div class="parrent"> <div id ...

Are you ready to put Jest to the test by checking the completion event of

The RxJS library's Observer triggers three main events: complete error next If we want to verify the occurrence of the complete event using Jest, how can this be achieved? For instance, we are able to test the next and error events by checking for ...

The alignment of the timeline in HTML CSS becomes distorted once it reaches the fourth element

As a newcomer to HTML, CSS, and JS, I am currently embarking on the task of creating a personal website for a course project. One of the pages on my website showcases a timeline featuring dates and information. While I have referred to a tutorial on W3scho ...

Is there a way to restrict Maven executions to only affect the build folder?

I'm currently working on a project that utilizes Maven and the frontend-maven-plugin (com.github.eirslett). Whenever I execute mvn install, all the plugin executions run, which in turn create folders like node_modules, bower_components, and node with ...

Displaying an IP camera feed on a three.js canvas

I've been presented with a seemingly straightforward task in JavaScript that I'm not very familiar with. The challenge is to take an IP camera stream and display it on a three.js canvas. To start, I came across an example that uses a webcam inst ...

Preserve identical elements within an array

I am looking to create an array of key:value pairs, even if there are duplicates present. My goal is to have an array of tasks, where each task consists of multiple operations. I only require the key/value for these operations. Currently, the value of th ...

What causes the Vuetify checkbox to trigger twice when clicked in a Vue.js application?

I am facing an issue with a table that contains checkboxes in every row. I want to trigger some logic when a checkbox is clicked. In some cases, I need to tick multiple rows when a checkbox is clicked, so I have set the checkboxes as readonly and handle th ...

How can I create a circular Datepicker in JavaFX?

Struggling with customizing my JavaFX application using CSS. Everything was going smoothly until I encountered the Datepicker. Despite trying various approaches, none seem to be working. Is there a way to round the Datepicker just like my TextFields? Here ...

NodeJS Query String failing to yield desired outcome

Currently experimenting with testing a URL query string in NodeJS const http = require('http'); const url = require('url'); http.createServer(function (req,res) { res.writeHead(200,{'Content-Type':'text/html'}); ...

Can streaming an HTTP response cause interference with Node.js processing?

As I explore the capabilities of Node.js under heavy loads, I am specifically interested in understanding how streaming a large response to a client may impact performance. To test this scenario, I set up a basic experiment where Node.js responds to every ...

Update an array while monitoring for a specific event

Working with Ionic, my goal is to push an array of an object when a specific event is emitted. This is what I currently have: export class PublicationService { constructor(private storage: Storage) {} private addPublicationSubject = new Be ...