如何在 Electron 中访问 <webview> 的 DOM?
How can I access the DOM of a <webview> in Electron?
我刚刚开始使用 Electron,之前使用过 node-webkit (nw.js)。
在 nw.js 中,我能够创建 iframe,然后访问所述 iframe 的 DOM 以获取标题、网站图标等内容。几天前,当我选择 Electron 将我的 nw.js 应用程序移植到它时,我看到了使用 webview 而不是 iframe 的建议,仅仅是因为它们更好。现在,我上面提到的功能在 nw.js 中相对容易实现,但我不知道如何在 Electron 中实现(而且例子很少到 none)。有人可以帮忙吗?
另外,我的 webview 有 back/forward 个按钮(而且我打算有多个)。我在文档中看到我可以在 webview 上调用函数来执行此操作,但我也没有尝试过(而且,我还没有找到它们在野外使用的例子)。
我不知道是谁投票结束了我的问题,但我很高兴它没有通过。其他人在网上其他地方也有这个问题。我也解释了我想要实现的目标,但是 w/e.
我最终使用了 ipc-message
。 documentation could use more examples/explanations for the layperson, but hey, I figured it out. My code is here and here,但如果我的代码因任何原因消失,我也会 post 下面的示例。
此代码在 aries.js
中,此文件包含在主渲染器页面中,即 index.html
。
var ipc = require("ipc");
var webview = document.getElementsByClassName("tabs-pane active")[0];
webview.addEventListener("ipc-message", function (e) {
if (e.channel === "window-data") {
// console.log(e.args[0]);
$(".tab.active .tab-favicon").attr("src", e.args[0].favicon);
$(".tab.active .tab-title").html(e.args[0].title);
$("#url-bar").val(e.args[0].url);
$("#aries-titlebar h1").html("Aries | " + e.args[0].title);
}
// TODO
// Make this better...cancel out setTimeout?
var timer;
if (e.channel === "mouseover-href") {
// console.log(e.args[0]);
$(".linker").html(e.args[0]).stop().addClass("active");
clearTimeout(timer);
timer = setTimeout(function () {
$(".linker").stop().removeClass("active");
}, 1500);
}
});
下一段代码在 browser.js
中,这个文件被注入到我的 <webview>
。
var ipc = require("ipc");
document.addEventListener("mouseover", function (e) {
var hoveredEl = e.target;
if (hoveredEl.tagName !== "A") {
return;
}
ipc.sendToHost("mouseover-href", hoveredEl.href);
});
document.addEventListener("DOMContentLoaded", function () {
var data = {
"title": document.title,
"url": window.location.href,
// need to make my own version, can't rely on Google forever
// maybe have this URL fetcher hosted on hikar.io?
"favicon": "https://www.google.com/s2/favicons?domain=" + window.location.href
};
ipc.sendToHost("window-data", data);
});
我还没有找到将 jQuery 注入 <webview>
的可靠方法,我可能不应该这样做,因为我要注入的页面可能已经有了它(以防你我想知道为什么我的主要代码是 jQuery,但也有常规的 JavaScript).
除了来宾主持 IPC 调用外 NetOperatorWibby, it is also very useful to go from host to guest. The only way to do this at present is to use the <webview>.executeJavaScript(code, userGesture)。这个 api 有点粗糙,但它有效。
如果您使用的是远程访客,例如 "extending" 第三方网页,您还可以利用 webview preload 属性,它会在任何其他脚本 [=22] 之前执行您的自定义脚本=] 在页面上。请注意,出于安全原因,预加载 api 将在自定义脚本完成时核对在自定义 JS 文件的根命名空间中创建的所有函数,但是此托管过程不会核对您在根。因此,如果您希望您的自定义函数持续存在,请将它们捆绑到一个单例对象中,您的自定义 API 将在页面完全加载后持续存在。
[update] 下面是我刚写完的一个简单例子:Electron-Webview-Host-to-Guest-RPC-Sample
这与之前的回答有关(不允许我发表评论):有关 ipc
Electron 1.x 用户模块的重要信息:
ipc 模块被拆分为两个独立的模块:
- ipcMain为主进程
- ipcRenderer 渲染进程
所以,上面的例子需要更正,而不是
// Outdated - doesn't work in 1.x
var ipc = require("ipc");
使用:
// In main process.
var ipcMain = require('electron').ipcMain
并且:
// In renderer process.
var ipcRenderer = require('electron').ipcRenderer
参见:http://electron.atom.io/blog/2015/11/17/electron-api-changes 部分 'Splitting the ipc module'
我刚刚开始使用 Electron,之前使用过 node-webkit (nw.js)。
在 nw.js 中,我能够创建 iframe,然后访问所述 iframe 的 DOM 以获取标题、网站图标等内容。几天前,当我选择 Electron 将我的 nw.js 应用程序移植到它时,我看到了使用 webview 而不是 iframe 的建议,仅仅是因为它们更好。现在,我上面提到的功能在 nw.js 中相对容易实现,但我不知道如何在 Electron 中实现(而且例子很少到 none)。有人可以帮忙吗?
另外,我的 webview 有 back/forward 个按钮(而且我打算有多个)。我在文档中看到我可以在 webview 上调用函数来执行此操作,但我也没有尝试过(而且,我还没有找到它们在野外使用的例子)。
我不知道是谁投票结束了我的问题,但我很高兴它没有通过。其他人在网上其他地方也有这个问题。我也解释了我想要实现的目标,但是 w/e.
我最终使用了 ipc-message
。 documentation could use more examples/explanations for the layperson, but hey, I figured it out. My code is here and here,但如果我的代码因任何原因消失,我也会 post 下面的示例。
此代码在 aries.js
中,此文件包含在主渲染器页面中,即 index.html
。
var ipc = require("ipc");
var webview = document.getElementsByClassName("tabs-pane active")[0];
webview.addEventListener("ipc-message", function (e) {
if (e.channel === "window-data") {
// console.log(e.args[0]);
$(".tab.active .tab-favicon").attr("src", e.args[0].favicon);
$(".tab.active .tab-title").html(e.args[0].title);
$("#url-bar").val(e.args[0].url);
$("#aries-titlebar h1").html("Aries | " + e.args[0].title);
}
// TODO
// Make this better...cancel out setTimeout?
var timer;
if (e.channel === "mouseover-href") {
// console.log(e.args[0]);
$(".linker").html(e.args[0]).stop().addClass("active");
clearTimeout(timer);
timer = setTimeout(function () {
$(".linker").stop().removeClass("active");
}, 1500);
}
});
下一段代码在 browser.js
中,这个文件被注入到我的 <webview>
。
var ipc = require("ipc");
document.addEventListener("mouseover", function (e) {
var hoveredEl = e.target;
if (hoveredEl.tagName !== "A") {
return;
}
ipc.sendToHost("mouseover-href", hoveredEl.href);
});
document.addEventListener("DOMContentLoaded", function () {
var data = {
"title": document.title,
"url": window.location.href,
// need to make my own version, can't rely on Google forever
// maybe have this URL fetcher hosted on hikar.io?
"favicon": "https://www.google.com/s2/favicons?domain=" + window.location.href
};
ipc.sendToHost("window-data", data);
});
我还没有找到将 jQuery 注入 <webview>
的可靠方法,我可能不应该这样做,因为我要注入的页面可能已经有了它(以防你我想知道为什么我的主要代码是 jQuery,但也有常规的 JavaScript).
除了来宾主持 IPC 调用外 NetOperatorWibby, it is also very useful to go from host to guest. The only way to do this at present is to use the <webview>.executeJavaScript(code, userGesture)。这个 api 有点粗糙,但它有效。
如果您使用的是远程访客,例如 "extending" 第三方网页,您还可以利用 webview preload 属性,它会在任何其他脚本 [=22] 之前执行您的自定义脚本=] 在页面上。请注意,出于安全原因,预加载 api 将在自定义脚本完成时核对在自定义 JS 文件的根命名空间中创建的所有函数,但是此托管过程不会核对您在根。因此,如果您希望您的自定义函数持续存在,请将它们捆绑到一个单例对象中,您的自定义 API 将在页面完全加载后持续存在。
[update] 下面是我刚写完的一个简单例子:Electron-Webview-Host-to-Guest-RPC-Sample
这与之前的回答有关(不允许我发表评论):有关 ipc
Electron 1.x 用户模块的重要信息:
ipc 模块被拆分为两个独立的模块:
- ipcMain为主进程
- ipcRenderer 渲染进程
所以,上面的例子需要更正,而不是
// Outdated - doesn't work in 1.x
var ipc = require("ipc");
使用:
// In main process.
var ipcMain = require('electron').ipcMain
并且:
// In renderer process.
var ipcRenderer = require('electron').ipcRenderer
参见:http://electron.atom.io/blog/2015/11/17/electron-api-changes 部分 'Splitting the ipc module'