2016-04-23 1 views
12

Lorsqu'il est exécuté dans le contexte Node (node-main),Vérifiez si le contexte WebKit est disponible dans NW.js

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

jette

nw n'est pas défini

parce que le contexte WebKit est pas prêt (dès le début, window n'est pas disponible dans NW.js < = 0,12, window.nw dans NW.js> = 0,13). Et

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

fonctionne très bien, mais setTimeout ressemble à un hack, la mise à valeur de retard en toute sécurité peut provoquer le décalage indésirable.

Comment la disponibilité du contexte WebKit et nw peut-elle être vérifiée à partir du contexte de nœud? Y a-t-il un moyen raisonnable, comme un événement qui pourrait être géré?

+0

L'exécution de votre fonction de noeud principal est-elle effectuée une fois que WebKit a chargé une option? –

+0

@RahatMahbub J'espérais qu'il existe une façon officielle (peut-être non documentée) de le faire uniquement via Node, comme un événement global.Cela aurait du sens, mais s'il n'y en a pas, alors rappeler de la page html est la seule option, je suppose. – estus

+0

@estus Il y a un moyen de le faire mais je ne pense pas que ce soit une manière particulièrement soignée. Je peux l'ajouter à ma réponse si tu veux. – Harry

Répondre

1

La solution que je suis venu d'abord en place ressemble

app-Node.js

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

app.html

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

Je serais heureux de savoir qu'il y a déjà un événement à écouter, donc les scripts client multiplate-forme pourraient omettre le code lié au NW.

2

Ce qui suit réalise la même chose mais fait l'inverse.

Dans votre fichier html:

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

Dans votre fichier JS nœud principal:

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

Ici, la fonction init est appelée uniquement lorsque le contexte Webkit/DOM est disponible.

2

Vous pouvez utiliser pollit :) ...

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

Je l'ai testé et il fonctionne pour moi :). Ceci modularise la solution que je donne vers la fin de ceci.

L'objet nw n'existe pas tant que webkit n'est pas opérationnel, c'est-à-dire que la fenêtre du navigateur a été créée. Cela se produit après le démarrage de Node. C'est la raison pour laquelle vous obtenez cette erreur. Pour utiliser l'API nw, vous pouvez soit créer des événements pouvant être écoutés , soit appeler des fonctions globales, la première étant préférable. Le code suivant va démontrer les deux et devrait vous donner une bonne idée de la façon dont Node et WebKit s'interfaçent les uns avec les autres.

Cet exemple crée une fenêtre, ouvre devtools et vous permet de basculer l'écran . Il affiche également l'emplacement de la souris dans la console. Il montre également comment envoyer des événements en utilisant le DOM, c'est-à-dire body.onclick() et en attachant des événements depuis Node, c'est-à-dire que nous allons capturer les événements minimize et les écrire sur la console.

Pour que cela fonctionne, vous devez utiliser la version SDK de NW. C'est mon paquet.JSON

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

Les deux fichiers dont vous avez besoin sont 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> 

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

Lors de l'exécution cela, j'utilisé

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

Vous pouvez ensuite ouvrir le navigateur en utilisant

http://localhost:1729/ 

pour le débogage en cas de besoin.

Si vous voulez faire quelque chose dès que l'objet nw existe, vous pouvez l'interroger. J'utiliserais eventEmitter, si vous ne voulez pas utiliser l'émetteur d'événements, vous pouvez tout aussi bien l'intégrer dans une fonction et l'appeler récursivement. Ce qui suit affichera combien de millisecondes il a fallu avant que l'objet nw ne soit configuré. Sur mon système, cela variait entre 43 et 48 millisecondes. Utiliser une fonction récursive n'était pas différent. Si vous ajoutez ceci au code ci-dessus, vous verrez tout ce qui est connecté à la console.

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

Merci pour paquet 'pollit', ressemble à un hack mais un bon, la performance et le retard excessif sont presque nulles. – estus

1

Solution 1:

Vous pouvez utiliser onload, 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" 
} 

Solution 2:

(Pour éviter les problèmes, mais ce n'est pas nécessaire).

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

Cette solution est erronée. require ('nw.gui') est le moyen hérité pour obtenir l'objet nw. Vous manquez également le point de l'OP sur les contextes, vous n'êtes pas dans le contexte du nœud à aucun moment dans cette réponse. – Harry

+0

@Harry c'est un exemple. –