在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可以被监听的事件,要么调用全局函数,前者更可取。 下面的代码将演示两者,并应该给你一个关于Node
和WebKit
如何相互连接的好主意。
这个例子创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相关的代码。