Accesso a variabili da Greasemonkey alla pagina e viceversa

Ho il seguente codice in test.js che viene eseguito subito prima di :

alert('stovetop'); alert(greasy); 

Ho il seguente codice in test.user.js :

 (function () { 'use strict'; var greasy = 'greasy variable'; document.title = 'greasy title'; }()); 

“stovetop” viene avvisato quindi so che il javascript della pagina funziona e document.title cambia, quindi so che lo script javascript funziona. Tuttavia, nella pagina Web ottengo l’errore:

Errore: ReferenceError: greasy non è definito Source File: /test.js

Come accedo alla pagina Web per accedere alla variabile impostata da Greasemonkey e per quanto riguarda il contrario?

  • Gli script Greasemonkey operano in un ambito separato e possono anche operare in una sandbox, a seconda delle impostazioni di @grant .

  • Inoltre, il codice della domanda isola il greasy in un ambito di funzione (come ha detto gladoscc).

  • Infine, per impostazione predefinita, test.js sparerà prima dello script di Greasemonkey, quindi non vedrà comunque alcuna variabile impostata. Utilizzare @run-at document-start per indirizzarlo.

Quindi, dato questo test.js , corri prima :

 window.targetPages_GlobalVar = 'stovetop'; console.log ("On target page, local global: ", targetPages_GlobalVar); console.log ("On target page, script global: ", gmScripts_GlobalVar); 

Quindi il seguente funzionerà:

Nessuna sandbox:

 // ==UserScript== // @name _Greasemonkey and target page, variable interaction // @include http://YOUR_SERVER.COM/YOUR_PATH/* // @include http://jsbin.com/esikut/* // @run-at document-start // @grant none // ==/UserScript== //--- For @grant none, could also use window. instead of unsafeWindow. unsafeWindow.gmScripts_GlobalVar = 'greasy'; console.log ("In GM script, local global: ", unsafeWindow.targetPages_GlobalVar); console.log ("In GM script, script global: ", gmScripts_GlobalVar); window.addEventListener ("DOMContentLoaded", function() { console.log ("In GM script, local global, after ready: ", unsafeWindow.targetPages_GlobalVar); }, false); 

Con sandbox, nessun ambito funzioni, unsafeWindow non unsafeWindow :
==> Aggiornamento importante: Greasemonkey ha cambiato la gestione di unsafeWindow con la versione 2.0, il successivo script di esempio non funzionerà con GM 2.0 o successivo . Le altre due soluzioni funzionano ancora.

 // ==UserScript== // @name _Greasemonkey and target page, variable interaction // @include http://YOUR_SERVER.COM/YOUR_PATH/* // @include http://jsbin.com/esikut/* // @run-at document-start // @grant GM_addStyle // ==/UserScript== /*- The @grant directive is needed to work around a design change introduced in GM 1.0. It restores the sandbox. */ unsafeWindow.gmScripts_GlobalVar = 'greasy'; console.log ("In GM script, local global: ", unsafeWindow.targetPages_GlobalVar); console.log ("In GM script, script global: ", unsafeWindow.gmScripts_GlobalVar); window.addEventListener ("DOMContentLoaded", function() { console.log ("In GM script, local global, after ready: ", unsafeWindow.targetPages_GlobalVar); }, false); 

Con sandbox, senza funzione scope, Script Injection :

 // ==UserScript== // @name _Greasemonkey and target page, variable interaction // @include http://YOUR_SERVER.COM/YOUR_PATH/* // @include http://jsbin.com/esikut/* // @run-at document-start // @grant GM_addStyle // ==/UserScript== /*- The @grant directive is needed to work around a design change introduced in GM 1.0. It restores the sandbox. */ function GM_main () { window.gmScripts_GlobalVar = 'greasy'; console.log ("In GM script, local global: ", window.targetPages_GlobalVar); console.log ("In GM script, script global: ", window.gmScripts_GlobalVar); window.addEventListener ("DOMContentLoaded", function() { console.log ("In GM script, local global, after ready: ", window.targetPages_GlobalVar); }, false); } addJS_Node (null, null, GM_main); function addJS_Node (text, s_URL, funcToRun, runOnLoad) { var D = document; var scriptNode = D.createElement ('script'); if (runOnLoad) { scriptNode.addEventListener ("load", runOnLoad, false); } scriptNode.type = "text/javascript"; if (text) scriptNode.textContent = text; if (s_URL) scriptNode.src = s_URL; if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()'; var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement; targ.appendChild (scriptNode); } 

Gli appunti:

  1. Puoi testare questi script su questa pagina (jsbin.com/esikut) .
  2. Senza sandbox, unsafeWindow e window non unsafeWindow sono le stesse.
  3. Tutti questi script producono lo stesso output sulla console:

     In GM script, local global: undefined In GM script, script global: greasy On target page, local global: stovetop On target page, script global: greasy In GM script, local global, after ready: stovetop 
  4. Il codice Script Injection funzionerà in una varietà di browser oltre a Firefox. unsafeWindow attualmente solo in Firefox + Greasemonkey (o Scriptish) o Chrome + Tampermonkey.

La variabile greasy è definita nell’ambito della funzione anonima. Non puoi accedere a greasy neanche nel tuo userscript, a meno che non faccia parte della tua funzione. Esempio:

 (function(){ var foo = 5; alert(foo); }(); alert(foo); //ERROR, because foo is undefined outside of the function. 

Fallo in questo modo:

 var foo = 5; (function(){ alert(foo); }(); alert(foo); 

Inoltre, perché stai mettendo tutto il tuo codice in una funzione anonima e poi eseguendolo?