2012-07-03 18 views
7

Muszę wywołać funkcję w zewnętrznym pliku ".js" z innego pliku ".js", bez odwoływania się do pliku zewnętrznego w tagu <head>.Wywołanie funkcji w jednym pliku JavaScript z innego pliku JavaScript?

Wiem, że jest możliwe, aby dynamicznie dodać zewnętrznego „js” plik do którego umożliwia dostęp do tego pliku, może to zrobić tak jak ...

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

Jednak ...

ten ma zastosowanie do mnie jako pliki zewnętrzne muszą być samodzielne pliki, które działają procedury rozruchu na ...

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

więc dodanie pełnego pliku dynamicznie się niepożądany efekt. Ponadto nie mogę wstępnie odwoływać się do pliku zewnętrznego w tagu <head>, ponieważ musi on być dynamiczny. Tak, ten plik zewnętrzny "test/testApp_1.js" zawiera funkcję, która zwraca zmienną string ...

function setAppLogo(){ 

var LogoFile = "test/TestApp_1_Logo.png"; 

return LogoFile; 
}  

muszę dostęp do każdej tej funkcji, albo mogę przechowywać ciąg jako globalnego var w pliku zewnętrznym ... tak czy inaczej jest w porządku, po prostu potrzebuję dostępu do wartości w LogoFile bez ładowania całego pliku zewnętrznego.

Ten problem sprawił, że poczułem się oszołomiony przez kilka godzin, więc wszelkie pomysły będą mile widziane.

+0

Dlaczego nie możesz dynamicznie dodawać w ''? domready nie uruchomi się, dopóki wszystkie JS, CSS i HTML nie zostaną załadowane ... – Rudie

+0

ponieważ dynamicznie dodając do głowy, kończę uruchomiony kod, który jest tu niechciany. Potrzebuję tylko jednej wartości zmiennej z tego pliku, a nie całego pliku. – user1005240

+0

Nie można załadować części pliku ... Można załadować ją za pomocą XHR, a następnie 'eval()' wynik ... Ale nie powinieneś. – Rudie

Odpowiedz

0

Chcesz załadować plik po załadowaniu jQuery za pomocą ajax, a następnie uruchomić odpowiedni skrypt w udanej funkcji ajax.

funkcja getScript Zobacz jQuery: 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

OP stwierdził, że "dodanie pełnego pliku dynamicznie ma niepożądany wpływ", jest to dokładnie to samo, co dodanie skryptu do nagłówka. – jbabey

+0

tak, ten kod uruchamia kompletny plik, który ma niepożądane efekty tutaj, naprawdę to, czego potrzebuję, to móc zanurzyć się w tym pliku i uruchomić tylko jedną funkcję, której potrzebuję, coś w rodzaju ... 'myFile.theFunctionineed();' lub pobierz wartość zmiennej w pliku, np. 'myFile.globalVar_1'' – user1005240

0

Jest możliwe, aby załadować cały skrypt poprzez XHR (np $.get in jQuery), a następnie analizować je, być może przy użyciu wyrażenia regularnego, aby wyodrębnić potrzebne części:

$.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 
}); 

Należy jednak zauważyć, że takie podejście może powodować trudności w utrzymaniu. Wyrażenia regularne nie są najlepszym narzędziem do analizy kodu JavaScript; powyższy przykład, na przykład, nie będzie parsować funkcji z zagnieżdżonymi {} blokami, które mogą istnieć w danym kodzie.

Zalecane może być znalezienie rozwiązania problemu po stronie serwera, np. dodanie wymaganej ścieżki skryptu lub jej części, zanim strona zostanie wysłana do przeglądarki.

+0

Podoba mi się twój pomysł! jest nieco wściekły, ale myślę, że to zadziałałoby ... mógłbym napisać funkcję, by wziąć plik, a następnie przeanalizować go pod kątem pożądanej funkcji, jego szalonego i prawdopodobnie złego pomysłu, ale tego "po wyjęciu z pudełka" fajnie jest się z tym zmierzyć! :) – user1005240

0

Nie jestem pewien, czy to dobry pomysł, ale można utworzyć element iframe i przeanalizować plik wewnątrz obiektu "okna", aby uniknąć większości niepożądanych efektów ubocznych (zakładając, że nie próbuje uzyskać dostępu do obiektu nadrzędnego). Następnie możesz uzyskać dostęp do dowolnej funkcji/zmiennej za pomocą obiektu okna iframe.

Przykład:

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(); 
}); 

to nie zagwarantuje, że sript w pliku nie może bałagan z dokumentem, ale nie jest prawdopodobne, jeśli pochodzi z zaufanego źródła.

Pamiętaj także o usunięciu ramki iframe po uzyskaniu tego, czego potrzebujesz.

1

Możesz skorzystać z posiadania pliku app.js, który zawiera globalne zmienne/wartości, które będziesz chciał używać z wielu miejsc. Powinieneś dołączyć ten plik .js na każdej stronie (i być może zminimalizować/połączyć go z innymi js, jeśli chcesz być sprytny i poprawić wydajność). Ogólnie rzecz biorąc, te globale powinny być dołączone do tworzonego obiektu, takiego jak var APPNAME = { }; ze zmiennymi/funkcjami, które będą używane z wielu miejsc.

Po uzyskaniu tego, zewnętrzny plik ".js", który chcesz wczytać, i ten, w którym aktualnie się znajdujesz, może uzyskać dostęp do globalnej zmiennej APPNAME i wszystkich jej atrybutów/funkcji i używać ich zgodnie z potrzebami. To może być lepsze podejście do uczynienia javascript bardziej modułowym i separowalnym. Mam nadzieję że to pomoże.

0

OK, dziękuję wszystkim za wszystkie dane wejściowe, ale myślę, że to, co próbowałem zrobić, nie jest obecnie możliwe, tj. Uzyskiwanie dostępu do funkcji z innego pliku bez załadowania tego pliku. Jednak znalazłem rozwiązanie mojego problemu. Teraz wysyłam zapytanie do mojego serwera o listę dostępnych aplikacji, a następnie używam tej listy do dynamicznego budowania aplikacji w interfejsie użytkownika. po wybraniu aplikacji mogę wtedy wywołać ten plik i funkcje w nim. Jest nieco bardziej złożony, ale dynamiczny, ma dobrą wydajność i działa. Jeszcze raz dziękuję za burzę mózgów! ;)

0

Może być to możliwe przy pomocy Web Workers. Byłbyś w stanie uruchomić swój skrypt, który chciałbyś wstrzyknąć w trochę odizolowane środowisko, aby nie zepsuł twojej bieżącej strony.

Jak już powiedziałeś, możliwe jest, że setAppLogo ma charakter globalny w zakresie "test/testApp_1.js", więc opieram się na tym oświadczeniu.

W oryginalnym scenariuszu należy utworzyć pracownika, które odniesienia do pliku skryptu pracownik + odsłuchania wiadomości, które pochodzą od pracownika:

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

Następnie w pracownika (worker.js), można użyj specjalnej funkcji importScripts (docs), która pozwala na załadowanie zewnętrznych skryptów do pliku roboczego, pracownik może również wyświetlić zmienne globalne tych skryptów. Dostępna jest również funkcja postMessage dostępna w module roboczym do wysyłania niestandardowych komunikatów z powrotem do oryginalnego skryptu, który z kolei nasłuchuje tych komunikatów (worker.onmessage). Kod dla 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()); 

Kiedy wywołuje dostaniesz wynik setAppLogo w was słuchacza:

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

Ten przykład jest bardzo prosty, choć należy przeczytać więcej na temat Web Workers API i możliwości pułapki.

Powiązane problemy