最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use electron tabs webview as to communicate from browser window to tabs? - Stack Overflow

programmeradmin1浏览0评论

I am trying to have my municate between different rendering processes in electron. Rather than have multiple windows I am using electron-tabs which can be found here. To start I simply want my main window to be able to send a message using ipcRenderer to each tab. With multiple windows, you could store each window in a global variable like this stack overflow question and then use the web-contents to send a message.

UPDATE: In the electron-tabs documentation, it suggests you can use the tabs webview the same as you would a windows web-contents (see here). Unfortunately, either I am missing something or it is a little more plicated.

For the code: I have a main window mainWindow.html

<html>
<head></head>
<body>
<div class="etabs-tabgroup" >
  <div class="etabs-tabs" ></div>
  <div class="etabs-buttons" style="padding:5px 0px"></div>
</div>
<div class="etabs-views"></div>
<link rel="stylesheet" href="node_modules/electron-tabs/electron-tabs.css">

<script>
const TabGroup = require('electron-tabs') ;
const electron = require('electron') ;
const {ipcRenderer} = electron;

var tabs = [];

// Create a new tabGroup
let tabGroup = new TabGroup();

// Add 3 tabs to tabGroup
for (var i = 0; i <3;i++){
    tabs.push(tabGroup.addTab({
        src: 'file://' + __dirname + '/tab.html',
        webviewAttributes: {
            nodeintegration: true
        }
    }));

    // Send test message to tabs... !!!! DOES NOT WORK !!!!
    circuitTabs[i].webview.send('testMessage',i);
}
</script>
</html>

tab.html

<!DOCTYPE html>
<html>
  <head>
  <meta name="viewport" content="width=device-width, initial-scale=1">  
  </head>
  <body>
      <script>
        const electron = require('electron') ;
        const {ipcRenderer} = electron;
        const { remote } = require('electron');

        ipcRenderer.on ('testMessage', (event, i) => { alert(`Message from main window to tab ${i}`); });

      </script>
  </body>
  </html>

main.js

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

let mainWindow = null;

app.on('ready', function () {
    mainWindow = new electron.BrowserWindow({width: 1200,height: 800,
    webPreferences: {
    nodeIntegration: true,
    webviewTag: true
    }
});

mainWindow.loadURL(path.join(__dirname, '/mainWindow.html'));
mainWindow.on('ready-to-show', function () {
    mainWindow.show();
    mainWindow.focus();
});

I am trying to have my municate between different rendering processes in electron. Rather than have multiple windows I am using electron-tabs which can be found here. To start I simply want my main window to be able to send a message using ipcRenderer to each tab. With multiple windows, you could store each window in a global variable like this stack overflow question and then use the web-contents to send a message.

UPDATE: In the electron-tabs documentation, it suggests you can use the tabs webview the same as you would a windows web-contents (see here). Unfortunately, either I am missing something or it is a little more plicated.

For the code: I have a main window mainWindow.html

<html>
<head></head>
<body>
<div class="etabs-tabgroup" >
  <div class="etabs-tabs" ></div>
  <div class="etabs-buttons" style="padding:5px 0px"></div>
</div>
<div class="etabs-views"></div>
<link rel="stylesheet" href="node_modules/electron-tabs/electron-tabs.css">

<script>
const TabGroup = require('electron-tabs') ;
const electron = require('electron') ;
const {ipcRenderer} = electron;

var tabs = [];

// Create a new tabGroup
let tabGroup = new TabGroup();

// Add 3 tabs to tabGroup
for (var i = 0; i <3;i++){
    tabs.push(tabGroup.addTab({
        src: 'file://' + __dirname + '/tab.html',
        webviewAttributes: {
            nodeintegration: true
        }
    }));

    // Send test message to tabs... !!!! DOES NOT WORK !!!!
    circuitTabs[i].webview.send('testMessage',i);
}
</script>
</html>

tab.html

<!DOCTYPE html>
<html>
  <head>
  <meta name="viewport" content="width=device-width, initial-scale=1">  
  </head>
  <body>
      <script>
        const electron = require('electron') ;
        const {ipcRenderer} = electron;
        const { remote } = require('electron');

        ipcRenderer.on ('testMessage', (event, i) => { alert(`Message from main window to tab ${i}`); });

      </script>
  </body>
  </html>

main.js

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

let mainWindow = null;

app.on('ready', function () {
    mainWindow = new electron.BrowserWindow({width: 1200,height: 800,
    webPreferences: {
    nodeIntegration: true,
    webviewTag: true
    }
});

mainWindow.loadURL(path.join(__dirname, '/mainWindow.html'));
mainWindow.on('ready-to-show', function () {
    mainWindow.show();
    mainWindow.focus();
});
Share Improve this question edited Jan 14, 2021 at 16:09 Jadon Erwin asked Jan 11, 2021 at 16:32 Jadon ErwinJadon Erwin 6717 silver badges31 bronze badges 5
  • 2 Maybe this is helpful? electronjs/docs/faq#how-to-share-data-between-web-pages – Michael Rush Commented Jan 13, 2021 at 17:00
  • 1 Yes, I think message ports might be the way to go. Thanks! Let's see if anyone es up with anything else. – Jadon Erwin Commented Jan 13, 2021 at 18:15
  • 1 I tried to use message ports but the example they give uses i-frames contentWindow to post messages. "iframe.contentWindow.postMessage(message, '*', [channel.port2]);" But, I don't see 'contentWindow' or any equivalent in the electron tabs documentation. – Jadon Erwin Commented Jan 13, 2021 at 19:13
  • 2 Hmm, ok. I can't really be of any help beyond that as I have never tried it. Maybe someone else with experience can chime in. – Michael Rush Commented Jan 13, 2021 at 21:44
  • 1 I got a little further. The electron tabs have a webview element that functions much like the web-contents. Still doesn't work... – Jadon Erwin Commented Jan 14, 2021 at 16:10
Add a ment  | 

2 Answers 2

Reset to default 4

I figured it out. You can get the webcontentsID from the tab and use ipcRenderer.sendTo function.

For the code: I have a main window mainWindow.html

<html>
<head></head>
<body>
<div class="etabs-tabgroup" >
  <div class="etabs-tabs" ></div>
  <div class="etabs-buttons" style="padding:5px 0px"></div>
</div>
<div class="etabs-views"></div>
<link rel="stylesheet" href="node_modules/electron-tabs/electron-tabs.css">

<script>
const TabGroup = require('electron-tabs') ;
const electron = require('electron') ;
const {ipcRenderer} = electron;

var tabs = [];

// Create a new tabGroup
let tabGroup = new TabGroup();

// Add 3 tabs to tabGroup
for (var i = 0; i <3;i++){
    tabs.push(tabGroup.addTab({
        src: 'file://' + __dirname + '/tab.html',
        webviewAttributes: {
            nodeintegration: true
        }
    }));

    // Send test message to tabs...
    var webContentsID = tabs[i].webview.getWebContentsId();
    ipcRenderer.sendTo(webContentsID,'testMessage');
}
</script>
</html>

tab.html

<!DOCTYPE html>
<html>
  <head>
  <meta name="viewport" content="width=device-width, initial-scale=1">  
  </head>
  <body>
      <script>
        const electron = require('electron') ;
        const {ipcRenderer} = electron;
        const { remote } = require('electron');

        ipcRenderer.on ('testMessage', (event, i) => { alert(`Message from main window to tab ${i}`); });

      </script>
  </body>
  </html>

main.js

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

let mainWindow = null;

app.on('ready', function () {
    mainWindow = new electron.BrowserWindow({width: 1200,height: 800,
    webPreferences: {
    nodeIntegration: true,
    webviewTag: true
    }
});

mainWindow.loadURL(path.join(__dirname, '/mainWindow.html'));
mainWindow.on('ready-to-show', function () {
    mainWindow.show();
    mainWindow.focus();
});

Try following this:

<webview>.send(channel, ...args)

channel String
...args any[]

Returns Promise<void>

Send an asynchronous message to renderer process via channel, you can also send arbitrary arguments. The renderer process can handle the message by listening to the channel event with the ipcRenderer module.

See webContents.send for examples.

Look at the docs below for more information.

https://www.electronjs/docs/api/webview-tag#webviewsendchannel-args

发布评论

评论列表(0)

  1. 暂无评论