检查 WebKit 上下文何时在 NW.js 中可用



在节点上下文(node-main)中执行时,

setTimeout(function () {
    console.log(nw);
}, 20);

抛出

未定义 NW

因为 WebKit 上下文尚未准备就绪(从一开始window在 NW.js <= 0.12 中不可用,window.nw在 NW.js>= 0.13 中不可用)。和

setTimeout(function () {
    console.log(nw);
}, 200);

工作正常,但setTimeout看起来像黑客,将其设置为安全延迟值可能会导致不希望的延迟。

如何从节点上下文检查WebKit上下文和nw的可用性?有没有合理的方法,比如可以处理的事件?

以下内容实现了相同的目标,但相反。

在您的 html 文件中:

<body onload="process.mainModule.exports.init()">

在您的节点主 JS 文件中:

exports.init = function() { console.log(nw); }

在这里,init 函数仅在 Webkit context/DOM 可用时调用。

您可以使用

pollit :)...

var pit = require("pollit");
foo = function(data) {
  console.log(nw);
};
pit.nw('nw', foo);    

我已经测试过它,它:)对我有用。这使我在本文末尾给出的解决方案模块化。

在webkit启动并运行(即浏览器)之前,nw对象不存在窗口已创建。这发生在 Node 启动后,这就是你收到此错误。要使用 nw api,您可以创建可以侦听或调用全局函数,前者更可取。下面的代码将演示两者,并应让您很好地了解NodeWebKit如何相互连接。

此示例创建一个窗口,打开 devtools,并允许您切换屏幕。它还在控制台中显示鼠标位置。它还演示了如何使用 DOM 即 body.onclick() 发送事件并从 Node 中附加事件,即我们将捕获minimize事件并将它们写入控制台。

为此,您需要使用 NW 的 SDK 版本。这是我的包.json

{
  "name": "hello",
  "node-main": "index.js",
  "main": "index.html",
  "window": {
    "toolbar": true,
    "width": 800,
    "height": 600
  },
  "dependencies" : {
    "robotjs" : "*",
    "markdown" : "*"
  }
}

您需要的两个文件index.html

<!DOCTYPE html>
<html>
  <head>
    <script>
      var win = nw.Window.get();
      global.win = win;
      global.console = console;
      global.main(nw);
      global.mouse();
      var markdown = require('markdown').markdown;
      document.write(markdown.toHTML("-->Click between the arrows to toggle full screen<---"));
    </script>
  </head>
  <body onclick="global.mouse();">
  </body>
</html>

index.js.

var robot = require("robotjs");
global.mouse = function() {
  var mouse = robot.getMousePos();
  console.log("Mouse is at x:" + mouse.x + " y:" + mouse.y);
  global.win.toggleFullscreen();
}
global.main = function(nw_passed_in) {
  global.win.showDevTools();
  console.log("Starting main");
  console.log(nw_passed_in);
  console.log(nw);
  global.win.on('minimize', function() {
    console.log('n: Window is minimized from Node');
  });
}

运行这个时,我使用

nwjs --enable-logging --remote-debugging-port=1729  ./

然后,您可以使用以下命令打开浏览器

http://localhost:1729/

如果需要,用于调试。

如果您想在nw对象存在后立即执行某些操作,则可以轮询它。我会使用 eventEmitter,如果你不想使用事件发射器,你可以很容易地把它包装在一个函数中并递归调用它。下面将显示在设置nw对象之前花费的毫秒数。在我的系统上,这在 43 - 48 毫秒之间。使用递归函数也不例外。如果将其添加到上面的代码中,您将看到所有内容都记录到控制台中。

var start = new Date().getTime();
var events = require('events');
var e = new events.EventEmitter();
var stop = 0;
e.on('foo', function() { 
if(typeof nw === 'undefined') {
  setTimeout(function () {
    e.emit('is_nw_defined');
  }, 1); 
 }   
 else {
   if(stop === 0) {
     stop = new Date().getTime();
   }   
   setTimeout(function () {
     console.log(stop - start);
     console.log(nw);
     e.emit('is_nw_defined');
   }, 2000);
 }   
});
e.emit('is_nw_defined');

解决方案 1:

您可以使用onload,请参阅参考。

主.js:

var gui = require("nw.gui"),
    win = gui.Window.get();
onload = function() {
    console.log("loaded");
    console.log(win.nw);
};

索引.html:

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="main.js"></script>
    </head>
    <body></body>
</html>

package.json:

{
  "name": "Freebox",
  "main": "index.html"
}

解决方案 2:

(为了防止出现问题,但这不是必需的)。

var gui = require("nw.gui"),
    win = gui.Window.get();
onload = function() {
    console.log("loaded");
    var a = function () {
        if (!win.nw) return setTimeout(a, 10);
        console.log(win.nw);
    };
};

我最初提出的解决方案看起来像

应用节点.js

process.once('webkit', () => {
    console.log(nw);
});

应用.html

<html>
<head>
    <script>
        global.process.emit('webkit');
    </script>
    ...
我很高兴

知道已经有一个事件要侦听,因此跨平台客户端脚本可以省略与 NW 相关的代码。

最新更新