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

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

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

nw没有定义

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

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

工作得很好,但setTimeout看起来像一个黑客,将其设置为安全延迟值可能会导致不必要的滞后。

如何从Node上下文中检查WebKit上下文和nw的可用性? 有没有合理的方法,就像一个可以处理的事件?

以下实现相同的事情,但反过来。

在你的html文件中:

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

在你的node-main JS文件中:

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

在这里,只有当Webkit上下文/ DOM可用时才调用init函数。

你可以使用pollit 🙂 …

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

我已经testing了它,它适用于我:)。 这模块化解决scheme,我给了接近这个结尾。

在webkit启动并运行之前, nw对象不存在,即浏览器窗口已经创build。 这发生在节点启动后,这就是为什么你得到这个错误。 要使用nw api,你要么创build可以被监听的事件,要么调用全局函数,前者更可取。 下面的代码将演示两者,并应该给你一个关于NodeWebKit如何相互连接的好主意。

这个例子创build一个Window,打开devtools并允许你切换屏幕。 它还显示控制台中的鼠标位置。 它还演示了如何使用DOM(例如body.onclick())发送事件,并从Node内部附加事件,即我们将捕获事件minimize并将其写入控制台。

为此,您需要使用NW的SDK版本。 这是我的package.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/ 

如果需要debugging。

如果你想尽快做一些事情,你可以轮询它。 我会使用eventEmitter,如果你不想使用事件发射器,你可以轻松地把它包装在一个函数中,并recursion地调用它。 以下将显示nw对象设置之前花费的毫秒数。 在我的系统上,这个范围在43 – 48毫秒之间。 使用recursion函数没有什么不同。 如果你把它添加到上面的代码中,你会看到所有logging到控制台的东西。

 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'); 

解决scheme1:

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

main.js:

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

index.html的:

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

的package.json:

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

解决scheme2:

(为了防止问题,但没有必要)。

 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); }; }; 

我最初的解决scheme看起来像

APP-的node.js

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

app.html

 <html> <head> <script> global.process.emit('webkit'); </script> ... 

我很高兴知道已经有一个事件要监听,所以跨平台的客户端脚本可能会忽略与NW相关的代码。