【问题标题】:How to dynamically change css style properties with Node and Electron如何使用 Node 和 Electron 动态更改 CSS 样式属性
【发布时间】:2020-03-13 01:44:18
【问题描述】:

我遇到了以下问题:我想在 Electron 中访问 styles.css 的 css 属性。问题是我不能使用document.getElementsByClassName(),因为Node 中没有document。所需的行为是在按下 q 键后更改一个 div 的颜色。 这是我的代码:

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;
}

编辑

经过 Gr8Miller 建议的修改(仍然没有通信): 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>

还有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...");
}

【问题讨论】:

    标签: javascript css node.js electron


    【解决方案1】:

    this 可能重复。

    尝试创建另一个包含您的代码的 js 文件并将其作为脚本从您的 html 文档加载。

    将此添加到您的 index.html:

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

    并使用您想要的代码创建一个单独的 pageScript.js 文件:

    window.onload = function () {
        // your code here
        function leftLight() {
            var element = ;
            element.style["background-color"] = "yellow";
        }
    
        // Also don't forget to call the function
        leftLight();
    }
    

    【讨论】:

      【解决方案2】:

      视图相关的任务应该在渲染进程而不是主进程中处理。

      在Electron 中,条目js(在您的情况下为index.js)在主进程中运行(它充当它创建的所有浏览器窗口的管理器)并且浏览器窗口本身在渲染进程中运行。 html元素和导入/嵌入的js在浏览器窗口中“live”/“run”(在渲染过程中),所以document只能在渲染过程中直接访问。

      在你的情况下。样式更改任务应该在渲染过程中完成:

      1. 按下键q,从主进程发送消息(例如key-pressed-q)以渲染进程:
      2. 在接收消息时更改渲染过程中的样式 (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>
          ...
      
      

      于 2019 年 11 月 18 日添加

      您的代码中还有其他错误需要修复,这些错误与电子无关,而只是 html 基础知识:

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

      getElementsByClassName 返回一个 Element(Array&lt;Element&gt;) 数组,但不返回单个 Element。 element.style 没有名为 background-color 的字段,应该是 backgroundColor。

      渲染进程中的console.log 不会在主进程的控制台中打印日志,它会输出到其托管浏览器窗口自己的控制台。如果要查看日志,必须先打开浏览器窗口的Devtools。

        // 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.
      });
      
      

      【讨论】:

      • 使用它使我无法在渲染和主进程之间进行通信。我添加了一些日志以确保它似乎发送但它没有在html文件的通道中接收。
      • @Norhther 有什么错误吗?也许您需要手动启用nodeIntegration,我修改了我的回复
      • @Norhther 你能告诉我你是如何检查index.html 是否收到消息的吗?根据您粘贴的代码,还有一些其他错误。
      【解决方案3】:

      将您的 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>
          <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>

      【讨论】:

      • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。
      猜你喜欢
      • 1970-01-01
      • 2012-02-06
      • 1970-01-01
      • 2019-08-18
      • 1970-01-01
      • 1970-01-01
      • 2017-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多