Jak niezawodnie i dynamicznie ładować plik JavaScript? Można to wykorzystać do zaimplementowania modułu lub komponentu, który po „zainicjowaniu” będzie dynamicznie ładował wszystkie potrzebne skrypty biblioteki JavaScript na żądanie.
Klient korzystający z komponentu nie musi wczytywać wszystkich plików skryptów biblioteki (i ręcznie wstawiać <script>
znaczniki na swojej stronie internetowej), które implementują ten komponent - tylko „główny” plik skryptu komponentu.
W jaki sposób główne biblioteki JavaScript osiągają to (Prototype, jQuery itp.)? Czy te narzędzia łączą wiele plików JavaScript w jedną przeznaczoną do redystrybucji wersję „kompilacji” pliku skryptu? A może wykonują jakieś dynamiczne ładowanie pomocniczych skryptów „bibliotecznych”?
Dodatek do tego pytania: czy istnieje sposób obsługi zdarzenia po załadowaniu dynamicznie dołączanego pliku JavaScript? Prototype służy document.observe
do wydarzeń obejmujących cały dokument. Przykład:
document.observe("dom:loaded", function() {
// initially hide all containers for tab content
$$('div.tabcontent').invoke('hide');
});
Jakie są dostępne zdarzenia dla elementu skryptu?
źródło
Odpowiedzi:
Możesz pisać dynamiczne tagi skryptów (używając Prototype ):
Problem polega na tym, że nie wiemy, kiedy zewnętrzny plik skryptu jest w pełni załadowany.
Często chcemy, aby nasz zależny kod znajdował się w następnej linii i lubimy pisać coś takiego:
Istnieje sprytny sposób na wstrzyknięcie zależności skryptu bez potrzeby wywołania zwrotnego. Wystarczy pobrać skrypt za pośrednictwem synchronicznego żądania AJAX i ocenić skrypt na poziomie globalnym.
Jeśli używasz Prototype, metoda Script.load wygląda następująco:
źródło
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)web.archive.org
.W javascript nie ma importu / dołączania / wymagania, ale są dwa główne sposoby osiągnięcia tego, co chcesz:
1 - Możesz załadować go za pomocą wywołania AJAX, a następnie użyć eval.
Jest to najprostszy sposób, ale jest ograniczony do Twojej domeny ze względu na ustawienia bezpieczeństwa Javascript, a używanie eval otwiera drzwi do błędów i hacków.
2 - Dodaj tag script z adresem URL skryptu w kodzie HTML.
Zdecydowanie najlepszy sposób. Możesz załadować skrypt nawet z obcego serwera i jest czysty, gdy używasz parsera przeglądarki do oceny kodu. Możesz umieścić tag w nagłówku strony internetowej lub na dole jej treści.
Oba te rozwiązania są tutaj omówione i zilustrowane.
Teraz jest duży problem, o którym musisz wiedzieć. Oznacza to, że zdalnie ładujesz kod. Nowoczesne przeglądarki internetowe załadują plik i będą wykonywać bieżący skrypt, ponieważ ładują wszystko asynchronicznie, aby poprawić wydajność.
Oznacza to, że jeśli użyjesz tych sztuczek bezpośrednio, nie będziesz mógł użyć nowo załadowanego kodu w następnej linii po tym, jak poprosiłeś o załadowanie, ponieważ nadal będzie się ładował.
Np .: my_lovely_script.js zawiera MySuperObject
Następnie ponownie ładujesz stronę, naciskając klawisz F5. I to działa! Mylące...
Więc co z tym zrobić?
Cóż, możesz skorzystać z hackowania, który autor sugeruje w linku, który ci dałem. Podsumowując, dla osób w pośpiechu używa en event do uruchomienia funkcji zwrotnej, gdy skrypt jest ładowany. Możesz więc umieścić cały kod za pomocą zdalnej biblioteki w funkcji wywołania zwrotnego. EG:
Następnie piszesz kod, którego chcesz użyć PO załadowaniu skryptu w funkcji lambda:
Następnie uruchom to wszystko:
Ok, rozumiem. Ale pisanie tego wszystkiego jest trudne.
Cóż, w takim przypadku możesz jak zwykle skorzystać z fantastycznego darmowego frameworka jQuery, który pozwoli ci zrobić to samo w jednej linii:
źródło
Użyłem ostatnio znacznie mniej skomplikowanej wersji z jQuery :
Działało świetnie w każdej przeglądarce, w której to testowałem: IE6 / 7, Firefox, Safari, Opera.
Aktualizacja: wersja bez jQuery:
źródło
$.getScript
. Zobacz moją odpowiedź.Zrobiłem w zasadzie to samo, co ty, Adam, ale z niewielką modyfikacją, aby upewnić się, że dodałem tag do głowy, aby wykonać zadanie. Po prostu utworzyłem funkcję dołączania (kod poniżej) do obsługi zarówno plików skryptu, jak i plików css.
Ta funkcja sprawdza również, czy skrypt lub plik CSS nie został jeszcze załadowany dynamicznie. Nie sprawdza ręcznie zakodowanych wartości i być może istniał lepszy sposób na zrobienie tego, ale spełnił swój cel.
źródło
kolejna niesamowita odpowiedź
https://stackoverflow.com/a/950146/671046
źródło
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)Oto przykładowy kod, który znalazłem ... czy ktoś ma lepszy sposób?
źródło
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)Jeśli masz już załadowane jQuery, powinieneś użyć $ .getScript .
Ma to przewagę nad innymi odpowiedziami tutaj, ponieważ masz wbudowaną funkcję zwrotną (aby zagwarantować, że skrypt zostanie załadowany przed uruchomieniem zależnego kodu) i możesz kontrolować buforowanie.
źródło
Jeśli chcesz załadować skrypt SYNC , musisz dodać tekst skryptu bezpośrednio do tagu HTML HEAD. Dodanie go jako wyzwoli obciążenie ASYNC . Aby synchronicznie załadować tekst skryptu z pliku zewnętrznego, użyj XHR. Poniżej krótka próbka (wykorzystuje części innych odpowiedzi w tym i innych postach):
źródło
Myślę, że samo dodanie skryptu do treści byłoby łatwiejsze niż dodanie go do ostatniego węzła na stronie. Co powiesz na to:
źródło
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)użyłem jeszcze innego rozwiązania, które znalazłem w sieci ... to jest pod Creative Commons i sprawdza, czy źródło zostało uwzględnione przed wywołaniem funkcji ...
plik można znaleźć tutaj: include.js
źródło
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)Właśnie dowiedziałem się o świetnej funkcji w YUI 3 (w momencie pisania tego tekstu dostępna w wersji zapoznawczej). Możesz łatwo wstawiać zależności do bibliotek YUI i do "zewnętrznych" modułów (czego szukasz) bez zbytniego kodu: YUI Loader .
Odpowiada również na drugie pytanie dotyczące funkcji wywoływanej po załadowaniu modułu zewnętrznego.
Przykład:
U mnie zadziałało idealnie i ma tę zaletę, że zarządza zależnościami. Zapoznaj się z dokumentacją YUI, aby zobaczyć przykład z kalendarzem YUI 2 .
źródło
Pojawił się nowy proponowany standard ECMA zwany importem dynamicznym , który został niedawno włączony do Chrome i Safari.
źródło
Technika, której używamy w pracy, polega na żądaniu pliku javascript za pomocą żądania AJAX, a następnie eval () zwraca. Jeśli używasz biblioteki prototypów, obsługują one tę funkcjonalność w swoim wywołaniu Ajax.Request.
źródło
jquery rozwiązało to dla mnie dzięki funkcji .append () - użyło tego do załadowania całego pakietu jquery ui
Do użycia - w nagłówku twojego html / php / etc po zaimportowaniu jquery.js po prostu włączysz ten jeden plik, aby załadować całą bibliotekę, dołączając go do głowy ...
źródło
Niech będzie ładny, krótki, prosty i łatwy w utrzymaniu! :]
Ten kod jest po prostu krótkim przykładem funkcjonalnym, który może wymagać dodatkowej funkcjonalności dla pełnego wsparcia na dowolnej (lub danej) platformie.
źródło
Dynamiczny import modułu wylądował w przeglądarce Firefox 67+ .
Z obsługą błędów:
Działa również dla wszelkiego rodzaju bibliotek niebędących modułami, w tym przypadku biblioteka jest dostępna w obiekcie okna w stary sposób, ale tylko na żądanie, co jest miłe.
Przykład użycia suncalc.js , serwer musi mieć włączony CORS, aby działał w ten sposób!
https://caniuse.com/#feat=es6-module-dynamic-import
źródło
Istnieją skrypty zaprojektowane specjalnie do tego celu.
yepnope.js jest wbudowany w Modernizr i lab.js jest bardziej zoptymalizowaną (ale mniej przyjazną dla użytkownika wersją.
Nie polecałbym tego robić za pomocą dużej biblioteki, takiej jak jquery lub prototyp - ponieważ jedną z głównych zalet programu ładującego skrypt jest możliwość wczesnego ładowania skryptów - nie powinieneś czekać, aż jquery i wszystkie elementy dom zostaną załadowane wcześniej uruchomienie sprawdzenia, czy chcesz dynamicznie załadować skrypt.
źródło
Napisałem prosty moduł, który automatyzuje zadanie importowania / włączania skryptów modułu w JavaScript. Spróbuj i poświęć trochę opinii! :) Szczegółowe wyjaśnienie kodu można znaleźć w tym poście na blogu: http://stamat.wordpress.com/2013/04/12/javascript-require-import-include-modules/
źródło
Zagubiłem się we wszystkich tych próbkach, ale dziś musiałem załadować zewnętrzny plik .js z mojego głównego .js i zrobiłem to:
źródło
Oto prosty z oddzwanianiem i obsługą IE:
źródło
Wiem, że moja odpowiedź jest nieco spóźniona na to pytanie, ale oto świetny artykuł na www.html5rocks.com - Głęboko zanurz się w mętnych wodach ładowania skryptów .
Z tego artykułu wynika, że jeśli chodzi o obsługę przeglądarek, najlepszym sposobem na dynamiczne ładowanie pliku JavaScript bez blokowania renderowania treści jest następujący sposób:
Biorąc pod uwagę, że masz cztery nazwane skrypty
script1.js, script2.js, script3.js, script4.js
, możesz to zrobić, stosując async = false :Teraz Spec mówi : Pobierz razem, wykonuj w kolejności, gdy tylko wszystko zostanie pobrane.
Firefox <3.6, Opera mówi: Nie mam pojęcia, co to za „asynchronizacja”, ale tak się składa, że wykonuję skrypty dodane przez JS w kolejności, w jakiej są dodawane.
Safari 5.0 mówi: Rozumiem „async”, ale nie rozumiem ustawiania go na „false” w JS. Wykonam twoje skrypty, gdy tylko wylądują, w dowolnej kolejności.
IE <10 mówi: Nie mam pojęcia o „async”, ale można obejść ten problem przy użyciu „onreadystatechange”.
Wszystko inne mówi: jestem twoim przyjacielem, zrobimy to na podstawie książki.
Teraz pełny kod z obejściem IE <10:
Kilka sztuczek i minifikacja później, to 362 bajty
źródło
Coś takiego...
źródło
Oto prosty przykład funkcji ładującej pliki JS. Istotne punkty:
$.ajax
lub$.getScript
możesz użyć wartości nonce, rozwiązując w ten sposób problemy z CSPunsafe-inline
. Wystarczy skorzystać z nieruchomościscript.nonce
Teraz używasz go po prostu przez
źródło
Absurdalna jedna linijka, dla tych, którzy uważają, że ładowanie biblioteki js nie powinno zająć więcej niż jednej linii kodu: P
Oczywiście, jeśli skrypt, który chcesz zaimportować, jest modułem, możesz użyć
import(...)
funkcji.źródło
Dzięki Obietnicom możesz to uprościć w ten sposób. Funkcja ładowarki:
Użycie (async / await):
Użycie (obietnica):
UWAGA: było jedno podobne rozwiązanie, ale nie sprawdza, czy skrypt jest już załadowany i ładuje skrypt za każdym razem. Ten sprawdza właściwość src.
źródło
wszystkie główne biblioteki javascript, takie jak jscript, prototype, YUI obsługują ładowanie plików skryptów. Na przykład w YUI, po załadowaniu rdzenia, możesz wykonać następujące czynności, aby załadować formant kalendarza
źródło
Poprawiłem niektóre z powyższych postów za pomocą przykładu roboczego. Tutaj możemy również podać css i js w tej samej tablicy.
źródło
Dla tych z Was, którzy kochają jednolinijki:
Istnieje prawdopodobieństwo, że pojawi się błąd, taki jak:
W takim przypadku możesz wrócić do:
źródło