2012-07-03 23 views
7

Ich muss eine Funktion in einer externen ".js" -Datei aus einer anderen ".js" -Datei aufrufen, ohne auf die externe Datei im Tag <head> zu verweisen.Eine Funktion in einer Javascript-Datei aus einer anderen Javascript-Datei aufrufen?

Ich weiß, dass es möglich ist, dynamisch auf eine externe „Js“ Datei auf die, die zu diesem Dateizugriff hinzufügen können, kann ich das tun, wie so ...

var AppFile = "test/testApp_1.js"; 
var NewScript=document.createElement('script'); 
var headID = document.getElementsByTagName("head")[0]; 
NewScript.src = AppFile; 
headID.appendChild(NewScript); 

jedoch ...

das ist nicht mir die Verwendung als die externen Dateien Stand-alone-Dateien sein müssen, die beim Start-up-Verfahren laufen ...

$(document).ready(function() 
{...} 

so hat die vollständige Datei hinzufügen dynamisch unerwünschtes beeinflussen. Außerdem kann ich die externe Datei im -Tag nicht vorreferenzieren, da sie dynamisch sein muss. Also, diese externe Datei "test/testApp_1.js" enthält eine Funktion, die einen String-Variable zurückgibt ...

function setAppLogo(){ 

var LogoFile = "test/TestApp_1_Logo.png"; 

return LogoFile; 
}  

Ich brauche Zugriff auf entweder dieser Funktion, oder ich könnte die Zeichenfolge als globale var in der externen Datei speichern ... Jeder Weg ist in Ordnung, ich brauche nur Zugriff auf den Wert in LogoFile ohne die gesamte externe Datei zu laden.

Dieser hat mich für ein paar Stunden jetzt ratlos, so dass alle Ideen sehr geschätzt würden.

+0

Warum können Sie das '' nicht dynamisch hinzufügen? domready wird nicht ausgelöst, bis alle JS und CSS und HTML geladen sind ... – Rudie

+0

weil ich den Code dynamisch hinzufüge, was hier unerwünscht ist. Ich brauche nur einen Variablenwert aus dieser Datei, nicht die ganze Datei. – user1005240

+0

Sie können nicht einen Teil der Datei laden ... Sie könnten es mit XHR laden und dann 'eval()' das Ergebnis ... Aber Sie sollten nicht. – Rudie

Antwort

0

Sie möchten die Datei laden, sobald jQuery mit AJAX geladen wurde, und dann das zugehörige Skript in der erfolgreichen AJAX-Funktion ausführen.

Siehe jQuery getScript Funktion: http://api.jquery.com/jQuery.getScript/

$(document).ready(function(){ 
$.getScript("http://domain.com/ajax/test.js", function(data, textStatus, jqxhr) { 
    console.log(data); //data returned 
    console.log(textStatus); //success 
    console.log(jqxhr.status); //200 
    console.log('Load was performed.'); 
    //run your second script executable code here 
}); 
}); 
+2

Das OP sagte, dass "das Hinzufügen der vollständigen Datei dynamisch einen unerwünschten Einfluss hat", dies ist genau dasselbe wie das Hinzufügen des Skripts zur Kopfzeile. – jbabey

+0

yeah, dieser Code führt die komplette Datei aus, die hier unerwünschte Effekte hat, wirklich was ich brauche ist in der Lage zu sein, in diese Datei einzutauchen und nur die eine Funktion auszuführen, die ich brauche, etwas wie ... 'myFile.theFunctionINeed();' oder erhalte den Wert einer Variablen innerhalb der Datei, zB 'myFile.globalVar_1' – user1005240

0

Es ist möglich, das gesamte Skript durch XHR (zB $.get in jQuery) und dann analysieren, um es zu laden, vielleicht einen regulären Ausdruck verwenden, um den benötigten Teil zu extrahieren:

$.get('pathtoscript.js', function(scriptBody) { 
    var regex = /function\s+setUpLogo\(\)\s*\{[^}]+}/g; 
    alert(scriptBody.match(regex)[0]); // supposed to output a function called 
             // 'setUpLogo' from the script, if the 
             // function does not have {} blocks inside 
}); 

Dennoch ist zu beachten, dass ein solcher Ansatz sehr wahrscheinlich Wartungshindernisse auslösen wird. Reguläre Ausdrücke sind kein optimales Werkzeug zum Parsen von JavaScript-Code. Das obige Beispiel analysiert beispielsweise keine Funktionen mit geschachtelten {} Blöcken, die im fraglichen Code durchaus vorhanden sein können.

Es könnte empfohlen werden, eine serverseitige Lösung für das Problem zu finden, z. Hinzufügen des erforderlichen Skriptpfads oder seines Teils, bevor die Seite an den Browser gesendet wird.

+0

Ich mag deine Idee! Es ist ein bisschen verrückt, aber ich denke, es würde funktionieren ... Ich könnte eine Funktion schreiben, um eine Datei aufzunehmen, dann parse es für die gewünschte Funktion, es ist verrückt und wahrscheinlich eine schlechte Idee, aber das "out of the box" Denken ist cool, um zu kommen! :) – user1005240

0

Ich bin mir nicht sicher, dass dies eine gute Idee ist, aber Sie können einen iframe erstellen und die Datei innerhalb seines 'window'-Objekts auswerten, um die meisten unerwünschten Nebenwirkungen zu vermeiden (vorausgesetzt, es versucht nicht, auf seine Eltern zuzugreifen). Dann können Sie über das Fensterobjekt des iframes auf die gewünschte Funktion/Variable zugreifen.

Beispiel:

function loadSomeJsInAFrame(url,cb) { 
     jQuery.get(url,function(res) { 
      iframe = jQuery('<iframe></iframe>').hide().appendTo(document.body); 
      iframe[0].contentWindow.eval(res); 
     if(cb) cb(iframe[0].contentWindow); 
    },'text'); 
} 

loadSomeJsInAFrame('test/testApp_1.js',function(frameWindow) { 
    console.log(frameWindow.setAppLogo()); 
    jQuery(frameWindow.frameElement).remove(); 
}); 

Dies garantiert nicht, dass der sript in der Datei kann nicht Chaos mit Ihrem Dokument, aber nicht wahrscheinlich, wenn es aus einer vertrauenswürdigen Quelle stammt.

Vergessen Sie auch nicht, Ihren iframe zu entfernen, nachdem Sie bekommen, was Sie davon brauchen.

1

Sie könnten von einer Art app.js Datei profitieren, die globale Variablen/Werte enthält, die Sie von vielen Orten verwenden möchten. Sie sollten diese .js Datei auf jeder Seite einfügen (und vielleicht verkleinern/verketten Sie es mit anderen js, wenn Sie clever sein und die Leistung verbessern wollen). Im Allgemeinen sollten diese Globals an ein Objekt angehängt werden, das Sie erstellen, wie var APPNAME = { }; mit Variablen/Funktionen, die von vielen Stellen verwendet werden.

Sobald Sie dies haben, kann die externe '.js'-Datei, die Sie laden möchten, und die, in der Sie sich gerade befinden, auf die globale APPNAME-Variable und alle ihre Attribute/Funktionen zugreifen und sie wie gewünscht verwenden. Dies könnte ein besserer Ansatz sein, um Ihr JavaScript modularer und separater zu machen. Hoffe das hilft.

0

Ok, danke an alle für die Eingabe, aber ich denke, dass das, was ich versuchte, momentan nicht möglich ist, d. H. Auf eine Funktion aus einer anderen Datei zugreifen, ohne diese Datei zu laden. Ich habe jedoch eine Lösung für mein Problem gefunden. Ich frage jetzt auf meinem Server nach einer Liste verfügbarer Apps. Anschließend verwende ich diese Liste, um die Apps in einer Benutzeroberfläche dynamisch zu erstellen. Wenn dann eine App ausgewählt wird, kann ich diese Datei und die darin enthaltenen Funktionen aufrufen. Es ist ein bisschen komplexer, aber es ist dynamisch, hat eine gute Leistung und es funktioniert. Nochmals vielen Dank für das Brainstorming! ;)

0

Es kann mit Hilfe von Web Workers möglich sein. Sie könnten Ihr Skript, das Sie injizieren möchten, in einer etwas isolierten Umgebung ausführen, damit es Ihre aktuelle Seite nicht durcheinanderbringt.

Wie Sie gesagt haben, ist es möglich, setAppLogo innerhalb von global zu sein, so werde ich auf diese Aussage verlassen.

In Ihrem ursprünglichen Skript Sie einen Arbeiter schaffen sollen, die Verweise auf eine Skriptdatei Arbeiter + Nachrichten abhören, die von dem Arbeiter kommen würden:

var worker = new Worker('worker.js'); 
worker.onmessage = function (e) { 
    // .... 
}; 

Dann werden in dem Arbeiter (worker.js), könnten Sie Verwenden Sie die Sonderfunktion importScripts (docs), die das Laden externer Skripts in Worker ermöglicht. Der Worker kann auch globale Variablen dieser Skripts anzeigen. Außerdem gibt es in Worker eine Funktion postMessage, die benutzerdefinierte Nachrichten an das ursprüngliche Skript zurücksendet, das wiederum diese Nachrichten abgehört (worker.onmessage). Code für worker.js:

importScripts('test/testApp_1.js'); 

// "setAppLogo" is now available to worker as it is global in 'test/testApp_1.js' 

// use Worker API to send message back to original script 
postMessage(setAppLogo()); 

Wenn es ruft Sie das Ergebnis setAppLogo in Ihnen Zuhörer erhalten: obwohl

worker.onmessage = function (e) { 
    console.log(e.data); // "test/TestApp_1_Logo.png" 
}; 

Dieses Beispiel sehr einfach ist, sollten Sie mehr über Web Worker API gelesen und möglich Fallstricke.

Verwandte Themen