【问题标题】:How can I access the DOM of a <webview> in Electron?如何在 Electron 中访问 <webview> 的 DOM?
【发布时间】:2016-02-05 00:36:20
【问题描述】:

我刚刚开始使用 Electron,之前有使用 node-webkit (nw.js) 的经验。

在 nw.js 中,我能够创建 iframe,然后访问所述 iframe 的 DOM,以获取标题、favicon 等内容。几天前,当我拿起 Electron 将我的 nw.js 应用程序移植到它时,我看到了使用 webviews 而不是 iframes 的建议,仅仅是因为它们更好。现在,我上面提到的功能在 nw.js 中相对容易实现,但我不知道如何在 Electron 中实现(示例很少)。有人可以帮忙吗?

另外,我的 webview 有后退/前进按钮(我打算有多个)。我在文档中看到我可以在 webview 上调用函数来执行此操作,但我尝试过的也没有任何效果(而且,我还没有找到在野外使用它们的示例)。

【问题讨论】:

标签: javascript jquery webview electron


【解决方案1】:

我不知道是谁投票结束了我的问题,但我很高兴它没有通过。其他人在网上其他地方也有这个问题。我还解释了我想要实现的目标,但是没有。


我最终使用了ipc-message。 documentation 可以为外行使用更多示例/解释,但是,嘿,我想通了。我的代码是here 和here,但如果我的代码由于某种原因消失,我也会在下面发布示例。


这段代码在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,这个文件被注入到我的&lt;webview&gt;。

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 注入&lt;webview&gt;s 的可靠方法,我可能不应该因为我要注入的页面可能已经有了它(如果你想知道为什么我的主要代码是 jQuery ,但也有常规的 JavaScript)。

【讨论】:

  • “这个文件被注入我的”是什么意思。您是在访客网站中包含文件还是通过一些电子代码进行注入?
  • webview 是一个 div。像
    。 Electron 允许我将 browser.js 放入正在加载网站的 webview 中。
  • 你是用preload属性放进去的吗? (github.com" preload="./test.js">)
  • @hippietrail 改用require("electron").ipcRenderer
【解决方案2】:

除了作为NetOperatorWibby 的guest 到host IPC 调用之外,从host 到guest 也非常有用。目前唯一的方法是使用<webview>.executeJavaScript(code, userGesture)。这个 api 有点粗,但是可以。

如果您正在使用远程访客,例如“扩展”第三方网页,您还可以使用 webview preload 属性,该属性会在页面上运行任何其他脚本之前执行您的自定义脚本。请注意,出于安全原因,preload api 将在您的自定义脚本完成时对在您的自定义 JS 文件的根命名空间中创建的任何函数进行核对,但是此保管过程不会核对您在根中声明的任何对象。因此,如果您希望自定义函数保持不变,请将它们捆绑到一个单例对象中,这样您的自定义 API 将在页面完全加载后保持不变。

[update] 这是我刚刚写完的一个简单例子:Electron-Webview-Host-to-Guest-RPC-Sample

【讨论】:

  • 嗯,我得试试。你有任何关于 executeJavaScript 函数的例子吗?
  • 当然可以。我将编写一个基本示例。
  • 我发布的示例非常基础,但您应该了解这个想法的要点。我昨晚刚遇到这个,所以我才刚刚开始,但我预见我将在来宾中编写一个处理程序,该处理程序接受 Base64 编码的 JSON 消息,该消息将在来宾处理程序中解码和处理。
  • 哦,哇,我刚刚试用了您的示例,非常棒!你真的很擅长 JavaScript,伙计!哈哈!
  • 哈哈。谢谢 =^) 我们正处于使用 Node 和 Electron 等工具的末日。当我在 2003 年开始进行繁重的 JS 编码时,这就是我梦寐以求的东西。
【解决方案3】:

这与之前的回答有关(我不允许发表评论):关于 Electron 1.x 用户的 ipc 模块的重要信息:

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“拆分 ipc 模块”部分

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-28
    • 2018-11-02
    • 2019-06-06
    • 2018-12-26
    • 1970-01-01
    • 2017-11-05
    • 2017-10-05
    • 2019-08-08
    相关资源
    最近更新 更多