出于性能原因,我在NW.JS中使用<webview>
标签代替了iFrame(出于性能原因),但找不到关于NWJS docs或实际{{3}的详细信息}。
我只是想从document.title
中检索<webview>
,然后将其发送回主进程。
答案 0 :(得分:1)
Webview的文档有限(可通过NWJS / Electron访问),因此很难弄清楚如何做一些基本的事情,例如访问Webview内部或从Webview内部进行访问,因此希望对您有所帮助。
FYI-在Electron和NWJS的上下文中,<webview>
标签允许您呈现网站(如iframe),其优点是可以在单独的过程中运行。这比一堆iframe的性能要好得多。 <webview>
包含一个标准HTML文档,之所以说iframe复杂,是因为它在单独的进程中运行。
在主进程和<webview>
内部之间进行通信的基本解决方案是使用Webview的自定义ContentWindow.postMessage()
方法。这高度基于window.postMessage()
。通过使用postMessage()
(特别是跟踪event.source
),我们在主进程和<webview>
之间建立了沟通桥梁。
它是如何工作的(至少是我找到的一种方法):
<webview>
和窗口(以稍后监听来自<webview>
内部的消息)<webview>
元素加载URL时,它会触发contentload()
contentload()
会将EventListener注入<webview>
中,并设置我们想从<webview>
内部获取的数据/ DOM元素。<webview>
一旦完成加载,就会触发loadstop()
loadstop()
将向<webview>
发送消息以建立网桥。重要的是要注意,这里我使用webview.contentWindow.postMessage()
而不是window.postMessage()
。<webview>
使用我们在步骤1设置的数据进行响应<webview>
接收回响应(通过EventListener“消息”)时,它将触发receiveHandshake()
receiveHandshake()
内部访问来自<webview>
内部的数据。这可以是页面标题,也可以是您在webviewInjectScript
中配置的任何内容。removeListeners()
删除了我们设置的所有EventListener,但是您可以继续来回发送消息。const webview = document.getElementById('your-webview-element');
// <webview> Content is loaded
function contentload() {
// The following will be injected in the webview
const webviewInjectScript = `
var data = {
title: document.title,
url: window.location.href
};
function respond(event) {
event.source.postMessage(data, '*');
}
window.addEventListener("message", respond, false);
`;
webview.executeScript({
code: webviewInjectScript
});
}
// <webview> Loading has finished
function loadstop() {
webview.contentWindow.postMessage("Send me your data!", "*"); // Send a request to the webview
}
// Bind events
webview.addEventListener("contentload", contentload);
webview.addEventListener("loadstop", loadstop);
window.addEventListener("message", receiveHandshake, false); // Listen for response
function receiveHandshake(event) {
// Data is accessible as event.data.*
// This is the custom object that was injected during contentload()
// i.e. event.data.title, event.data.url
console.log(event.data)
// Unbind EventListeners
removeListeners();
}
// Remove all event listeners
function removeListeners() {
webview.removeEventListener("loadstart", loadstart);
webview.removeEventListener("contentload", contentload);
webview.removeEventListener("loadstop", loadstop);
window.removeEventListener("message", receiveHandshake);
}
(注意:仅在NW.JS中测试)有关Electron的Webview支持,请参见:here。还有another thread关于在Electron中使用IPC的信息。 NW.JS对我来说不是一个选择。