JQuery, aby dynamicznie ładować plik Javascript

134

Mam bardzo duży plik javascript, który chciałbym załadować tylko wtedy, gdy użytkownik kliknie określony przycisk. Jako ramy używam jQuery. Czy istnieje wbudowana metoda lub wtyczka, która pomoże mi to zrobić?

Więcej szczegółów: Mam przycisk „Dodaj komentarz”, który powinien załadować plik javascript TinyMCE (zagotowałem wszystkie rzeczy TinyMCE do jednego pliku JS), a następnie wywołać tinyMCE.init (...).

Nie chcę tego wczytywać podczas początkowego ładowania strony, ponieważ nie każdy kliknie „Dodaj komentarz”.

Rozumiem, że mogę po prostu zrobić:

$("#addComment").click(function(e) { document.write("<script...") });

ale czy jest lepszy / zamknięty sposób?

Jeff Meatball Yang
źródło
To świetne rozwidlenie kompresora TinyMCE, który dodaje asynchroniczne ładowanie TinyMCE przez wtyczkę jQuery.tinyMCE i obejmuje Gzip, konkatenację i minifikację: github.com/bobbravo2/tinymce_compressor/blob/master/ ...
Bob Gregor

Odpowiedzi:

200

Tak, użyj getScript zamiast document.write - pozwoli to nawet na wywołanie zwrotne po załadowaniu pliku.

Możesz jednak chcieć sprawdzić, czy TinyMCE jest zdefiniowane przed włączeniem go (dla kolejnych wywołań `` Dodaj komentarz ''), aby kod mógł wyglądać mniej więcej tak:

$('#add_comment').click(function() {
    if(typeof TinyMCE == "undefined") {
        $.getScript('tinymce.js', function() {
            TinyMCE.init();
        });
    }
});

initTo znaczy zakładając, że będziesz musiał do niego zadzwonić tylko raz. Jeśli nie, możesz to rozgryźć stąd :)

Paolo Bergantino
źródło
3
@Jose: Dzięki :), @Jeff: Nie ma problemu. Jeśli chodzi o wspaniałość jQuery, ta jest dość nieznana.
Paolo Bergantino
1
TLDR; rób to tylko wtedy, gdy skrypty znajdują się w tym samym katalogu. Dłuższa wersja: getScript w rzeczywistości umieszcza javascript w bieżących wycinkach zamiast na stronie. co to oznacza, że ​​wszelkie ścieżki w dołączonym javascript będą względne do bieżącego dokumentu.
Tom Carchrae
23

Zdaję sobie sprawę, że jestem trochę spóźniony (około 5 lat), ale myślę, że jest lepsza odpowiedź niż zaakceptowana, jak następuje:

$("#addComment").click(function() {
    if(typeof TinyMCE === "undefined") {
        $.ajax({
            url: "tinymce.js",
            dataType: "script",
            cache: true,
            success: function() {
                TinyMCE.init();
            }
        });
    }
});

Ta getScript()funkcja faktycznie zapobiega buforowaniu przeglądarki . Jeśli uruchomisz śledzenie, zobaczysz, że skrypt jest ładowany z adresem URL zawierającym parametr timestamp:

http://www.yoursite.com/js/tinymce.js?_=1399055841840

Jeśli użytkownik kliknie #addCommentlink wiele razy, tinymce.jszostanie ponownie załadowany z adresu URL z inną sygnaturą czasową. To mija się z celem buforowania przeglądarki.

===

Alternatywnie w getScript()dokumentacji znajduje się przykładowy kod, który pokazuje, jak włączyć buforowanie, tworząc funkcję niestandardową cachedScript()w następujący sposób:

jQuery.cachedScript = function( url, options ) {

    // Allow user to set any option except for dataType, cache, and url
    options = $.extend( options || {}, {
        dataType: "script",
        cache: true,
        url: url
    });

    // Use $.ajax() since it is more flexible than $.getScript
    // Return the jqXHR object so we can chain callbacks
    return jQuery.ajax( options );
};

// Usage
$.cachedScript( "ajax/test.js" ).done(function( script, textStatus ) {
    console.log( textStatus );
});

===

Jeśli chcesz globalnie wyłączyć buforowanie, możesz to zrobić ajaxSetup()w następujący sposób:

$.ajaxSetup({
    cache: true
});
dana
źródło
To mogło nie być dostępne, kiedy to pisałeś, ale pamiętaj, że jQuery umożliwia (globalnie) wyłączenie tej funkcji bez buforowania i ponowne zezwolenie na buforowanie. Zobacz api.jquery.com/jQuery.getScript/#caching-requests (Och, widzę, że podejście $ .ajax (), które tu omawiasz , jest tam również wspomniane.)
Peter Hansen
@PeterHansen - Dzięki za wskazówkę. Zaktualizowałem moją odpowiedź twoją sugestią.
dana
3
jQuery 1.12.0 lub nowszej wsparcie wyłączenie inline anticache tak:$.getScript({url: "test.js",cache:true})
oriadam