7

Es gibt eine Seite http://example.com/1.php, die JavaScript-Datei wie gewohnt beinhaltet:window.onload funktioniert in Firefox + Greasemonkey-Skript, aber nicht in einem Chrome-Benutzer-Skript?

<script type="text/javascript" src="/util.js?1354729400"></script> 

Diese Datei enthält Funktion exampleFunction namens, die ich brauche in meinem userscript zu verwenden. Auch habe ich ein Benutzerskript:

// ==UserScript== 
// @name   SomeName 
// @namespace  http://example.com/userscripts 
// @description Greets the world 
// @include  http://example.com/* 
// ==/UserScript== 
window.onload = function() { 
     console.log(exampleFunction); 
     alert("LOADED!"); 
} 

, die perfekt in Firefox funktioniert und gibt einen Fehler in Chrome:

Uncaught ReferenceError: exampleFunction is not defined 

Wie kann ich es funktioniert?

+0

Versuchen Sie, Cache auf Chrom zu deaktivieren, oder drücken Sie STRG + F5 – Ibu

+0

Es hilft nicht – Alex

Antwort

9

Der Grund dafür, dass nicht definiert wurde, liegt daran, dass Chrome-Benutzer in einer Sandbox arbeiten ("isolated world"). Beachten Sie, dass Greasemonkey-Skripts oft auch in einer Sandbox funktionieren, aber Ihre ist derzeit läuft mit an implicit @grant none.
Wenn Ihr Skript eine GM_ Funktion verwenden würde, würde es auch in Firefox nicht mehr funktionieren.

Verwenden Sie Script Injectionsimilar to this answer, damit dieses Skript in beiden Browsern (und einigen anderen) funktioniert.

Allerdings, gibt es eine andere Kupplung, da das Skript window.onload verwendet. Chrome userscripts, with the default execution start-mode, will often never see the onload event.

Um das zu umgehen, fügen Sie // @run-at document-end zum Metadatenblock hinzu.

So das Skript wird:

// ==UserScript== 
// @name   SomeName 
// @namespace  http://example.com/userscripts 
// @description  Greets the world 
// @include   http://example.com/* 
// @run-at   document-end 
// @grant   none 
// ==/UserScript== 

function GM_main() { 
    window.onload = function() { 
     console.log(exampleFunction); 
     alert("LOADED!"); 
    } 
} 

addJS_Node (null, null, GM_main); 

//-- This is a standard-ish utility function: 
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); 
} 
+0

Es funktioniert nicht immer ... Und ich kann den Grund dafür nicht feststellen – Alex

+1

** Wie ** ist es "nicht funktioniert"? Was sind die Symptome *** genau ***? Verwenden Sie das Skript aus der Antwort ohne Änderungen, aber die Zeile "@ include". ** Wie lautet die URL der Seite **, auf der das Skript nicht funktioniert? Nimmt diese Seite eine lange Zeit um * vollständig * zu laden? 'onload' wird nicht ausgelöst, bis das letzte große Bild usw. heruntergeladen wurde. –

+0

Probieren Sie es selbst aus: Entfernen Sie "console.log (exampleFunction);" und lassen Sie "alert" aus dem Skript. Bleiben Sie auf dieser Seite, klicken Sie auf Ihren Profillink und aktualisieren Sie diese Seite mehrmals. Wie funktioniert es für dich? Ich bekomme kein Onload-Ereignis in der Hälfte der Fälle überhaupt – Alex

1

Haben Sie versucht, examplefunction mit eckigen Klammern aufzurufen? :) So:

console.log(exampleFunction()); 

Wenn Sie es in Chromkonsole versuchen, müssen Sie Klammern hinzufügen Funktion aufzurufen.

+1

Das wird nichts tun, wenn exampleFunction wirklich undefiniert ist. – Stuart

1

Wenn Sie das entspricht onLoad wollen, die nicht ausgelöst, bis alle Bilder auf der Seite geladen werden, Sie // @run-at document-idle in Ihrem Metadatenblock verwenden möchten. Die Standardeinstellung, document-end, wird beim Laden des DOM ausgelöst, das entspricht der Datei document.ready.