如何在Electron中访问<webview>的DOM?

时间:2015-11-04 13:28:42

标签: javascript jquery webview electron

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

在nw.js中,我能够创建iframe,然后访问所述iframe的DOM,以便获取标题,favicon和c等内容。几天前我拿起Electron把我的nw.js应用程序移植到它上面时,我看到了使用webviews代替iframe的建议,只是因为它们更好。现在,我在上面提到的功能在nw.js中相对比较容易,但是我不知道如何在Electron中做到这一点(例子很简单)。有人可以帮忙吗?

另外,我的webview有后退/前进按钮(我打算有多个)。我在文档中看到我可以在webview上调用函数,但我没有尝试过任何工作(并且,我没有找到它们在野外使用的例子)。

3 个答案:

答案 0 :(得分:9)

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

我最终使用ipc-messagedocumentation可以为外行使用更多的例子/解释,但是嘿,我明白了。我的代码是herehere,但如果我的代码因任何原因消失,我也会在下面发布示例。

此代码位于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>,我可能不应该因为我要注入的页面可能已经拥有它(以防你&#39;我想知道为什么我的主要代码是jQuery,但也有常规的JavaScript)。

答案 1 :(得分:6)

除了作为NetOperatorWibby主持IPC呼叫的访客之外,从主机到访客也非常有用。目前唯一的方法是使用<webview>.executeJavaScript(code, userGesture)。这个api有点粗糙,但它确实有效。

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

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

答案 2 :(得分:0)

这与先前的答案(我不允许发表评论)有关:关于电子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部分&#39;拆分ipc模块&#39;