2016-04-23 7 views
12

Wenn im Knoten Kontext ausgeführt (node-main),prüfen, wenn WebKit Kontext in NW.js verfügbar ist

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

wirft

nw nicht

definiert ist

weil WebKit Kontext nicht bereit (von Anfang an ist window in NW.js nicht verfügbar < = 0.12, window.nw in NW.js> = 0.13). Und

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

funktioniert nur gut, aber setTimeout sieht aus wie ein Hack, um es zu sicherem Verzögerungswert einstellen kann unerwünschte Verzögerung verursachen.

Wie kann die Verfügbarkeit des WebKit-Kontexts und nw vom Knotenkontext aus überprüft werden? Gibt es einen vernünftigen Weg, wie ein Ereignis, das bearbeitet werden könnte?

+0

Wird Ihre Knoten-Hauptfunktion ausgeführt, sobald WebKit eine Option lädt? –

+0

@RahatMahbub Ich hatte gehofft, dass es einen offiziellen (vielleicht undokumentierten) Weg gibt, dies allein durch Node zu tun, wie das globale Ereignis.Dies würde Sinn machen, aber wenn es keinen gibt, dann ist das Zurückrufen von der HTML-Seite die einzige Option, denke ich. – estus

+0

@estus Es gibt einen Weg, es zu tun, aber ich denke nicht, dass es ein besonders netter Weg ist. Ich kann es meiner Antwort hinzufügen, wenn Sie möchten. – Harry

Antwort

1

Die Lösung Ich bin gekommen, zunächst aussieht wie oben

app-node.js

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

app.html

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

Ich würde mich freuen zu hören, dass bereits ein Ereignis zu hören ist, sodass plattformübergreifende Clientskripte den NW-Code weglassen könnten.

2

Das Folgende erreicht das Gleiche, aber umgekehrt.

in Ihrer HTML-Datei:

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

In Ihrer Knoten-Haupt JS-Datei:

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

Hier wird init-Funktion nur aufgerufen, wenn Webkit Kontext/DOM zur Verfügung steht.

2

Sie pollit verwenden könnte :) ...

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

Ich habe es getestet und es funktioniert für mich :). Dies modularisiert die Lösung, die ich am Ende davon gebe.

Das Objekt nw existiert nicht, bis Webkit läuft und der Browser Fenster erstellt wurde. Dies geschieht, nachdem Node gestartet wurde, weshalb Sie bekommen, diesen Fehler zu bekommen. Um die nw API zu verwenden, erstellen Sie entweder Ereignisse, die angehört werden können, oder rufen globale Funktionen auf, wobei die erste bevorzugt wird. Der folgende Code demonstriert beide und sollte Ihnen eine gute Vorstellung davon geben, wie Node und WebKit miteinander kommunizieren.

Dieses Beispiel erstellt ein Fenster, öffnet Devtools und ermöglicht es Ihnen, den Bildschirm umzuschalten. Es zeigt auch die Mausposition in der Konsole an. Es zeigt auch, wie Ereignisse mit dem DOM gesendet werden, dh body.onclick() und Ereignisse von innerhalb von Node anhängen, dh wir werden minimize Ereignisse fangen und sie auf die Konsole schreiben.

Damit dies funktioniert, müssen Sie die SDK-Version NW verwenden. Das ist mein Paket.json

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

Die beiden Dateien, die Sie brauchen, sind 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> 

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

Wenn dies ausgeführt habe ich

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

können Sie dann den Browser

http://localhost:1729/ 

für das Debuggen mit öffnen, wenn nötig.

Wenn Sie etwas tun möchten, sobald das Objekt nw existiert, können Sie es abfragen. Ich würde eventEmitter verwenden, wenn Sie den Ereignisemitter nicht verwenden möchten, können Sie ihn genauso einfach in eine Funktion einfügen und rekursiv aufrufen. Im Folgenden wird angezeigt, wie viele Millisekunden das Objekt nw benötigt wurde. Auf meinem System reichte das zwischen 43 - 48 Millisekunden. Die Verwendung einer rekursiven Funktion war nicht anders. Wenn Sie dem obigen Code hinzufügen, sehen Sie alles, was in der Konsole protokolliert wurde.

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

Danke für 'Pollit' Paket, sieht aus wie ein Hack, aber ein guter, Performance-Hit und übermäßige Verzögerung sind fast Null. – estus

1

Lösung 1:

können Sie onload verwenden, see reference.

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" 
} 

Lösung 2:

(Um Probleme zu vermeiden, aber es ist nicht notwendig).

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

Diese Lösung ist falsch. require ('nw.gui') ist der alte Weg, um das neue Objekt zu erhalten. Wenn Sie auch den OP-Punkt zu Kontexten übersehen, befinden Sie sich zu keinem Zeitpunkt in dieser Antwort im Knoten-Kontext. – Harry

+0

@Harry es ist ein Beispiel. –