2010-09-08 4 views
2

J'ai un script qui a utilisé unsafeWindow dans FireFox, puisque cela n'a pas fonctionné, j'ai cherché une autre option, et je l'ai trouvé, je me demande seulement: Comment puis-je utiliser une variable de mon userscript dans la solution de contournement unsafeWindow?Injecter JS dans la page de Google Chrome avec des variables du script d'utilisateur?

Mon code est:

// ==UserScript== 
// @name Test 
// @description Test 
// @include http://www.google* 
// ==/UserScript== 

var toAlert = "This is what I want to alert..."; 
alert("Before implementation..."); 
contentEval(function(){ alert(toAlert);}); 
alert("And after..."); 
function contentEval(source) { 
    // Check for function input. 
    if ('function' == typeof source) { 
    // Execute this function with no arguments, by adding parentheses. 
    // One set around the function, required for valid syntax, and a 
    // second empty set calls the surrounded function. 
    source = '(' + source + ')();' 
    } 

    // Create a script node holding this source code. 
    var script = document.createElement('script'); 
    script.setAttribute("type", "application/javascript"); 
    script.textContent = source; 

    // Insert the script node into the page, so it will run, and immediately 
    // remove it to clean up. 
    document.body.appendChild(script); 
    document.body.removeChild(script); 
} 

Et ça ne fonctionne pas ... Qu'est-ce que je fais mal?

+0

vous ajoutez le script et le supprimez immédiatement, je doute que cela puisse être une raison. – Neutralizer

+0

veuillez également vous assurer que votre fonction "contentEval" fonctionne correctement. – Neutralizer

Répondre

4

Votre script fonctionnerait si toAlert était défini dans l'étendue globale de la page.

Dans Chrome, extension/Greasemonkey JavaScript ne peut pas partager des variables ou des fermetures avec la page JavaScript. C'est pourquoi vous ne pouvez pas injecter directement cette fonction, de la portée de l'extension à la portée de la page, mais devez la recréer à partir d'une chaîne source.

Cela signifie que si vous créez une fonction dans le périmètre de la page, toutes les variables ou fonctions que votre fonction requiert doit soit:

  1. être déjà présent, globalement, dans la page source.
    Ou
  2. Etre scripté dans la page source également.

Par exemple, la modification du code comme si ...

//-- Must recreate the variable that the function requires. 
scriptStr = 'var toAlert="' + toAlert +'";'; 

//-- Now the function. 
scriptStr += '(' + source.toString() + ')();' 

var script = document.createElement('script'); 
script.textContent = scriptStr; 

... fonctionne, mais cette approche devient évidemment désordre. La meilleure chose à faire est de:
(A) garder tout votre JavaScript dans l'extension; N'interagissez pas avec le JavaScript de la page.

(B) si vous devez interagir avec les JS de page ou les bibliothèques de charge comme jQuery, puis mettre tous de votre code dans une fonction principale() et un script dans la page source.

Comme si:

function localMain() 
{ 
    /*--- Put EVERYTHING inside this wrapper, functions and variables. 
     Call or use nothing else that's defined in the GM script here. 
     Can use objects in the source page's scope, though. 
    */ 
} 

//--- Now create the function in the page's scope and run it. 
var scriptNode   = document.createElement ("script"); 
scriptNode.textContent = localMain.toString() + "\n localMain();"; 
document.head.appendChild (scriptNode); 

Notez que si vous chargez une bibliothèque dans le périmètre de la page, vous devrez peut-être retarder l'exécution localMain() par l'utilisation d'une minuterie et d'un chèque de cette bibliothèque .

+0

Merci, j'ai utilisé la première option et ça marche super bien! – ManIkWeet

+0

De rien. Heureux de vous aider. –

Questions connexes