JQuery динамічно завантажує файл Javascript


134

У мене дуже великий файл JavaScript, який я хотів би завантажити, лише якщо користувач натискає певну кнопку. Я використовую jQuery як свою основу. Чи є вбудований метод або плагін, який допоможе мені це зробити?

Ще кілька деталей: у мене є кнопка «Додати коментар», яка повинна завантажувати файл JavaScript TinyMCE (я перемістив усі речі TinyMCE до одного файлу JS), а потім зателефонуйте tinyMCE.init (...).

Я не хочу завантажувати це під час початкового завантаження сторінки, оскільки не всі натискають "Додати коментар".

Я розумію, що можу просто зробити:

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

але чи є кращий / капсульований спосіб?


Це чудова вилка компресора TinyMCE, яка додає асинхронне завантаження TinyMCE через плагін jQuery.tinyMCE і включає Gzip, конкатенацію та мінімізацію: github.com/bobbravo2/tinymce_compressor/blob/master/…
Боб Грегор

Відповіді:


200

Так, використовуйте getScript замість document.write - це навіть дозволить отримати зворотний дзвінок після завантаження файлу.

Ви можете перевірити, чи визначено TinyMCE, перш ніж включити його (для наступних дзвінків на "Додати коментар"), щоб код міг виглядати приблизно так:

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

Якщо припустити, що вам потрібно зателефонувати initлише один раз, тобто. Якщо ні, ви можете це зрозуміти звідси :)


3
@Jose: Спасибі :), @Jeff: Немає проблем. Що стосується дивовижності jQuery, ця проблема є досить невідомою.
Паоло Бергантіно

1
TLDR; робити це лише у тому випадку, якщо сценарії знаходяться в одному каталозі. Довша версія: getScript фактично вводить javascript у поточні сценарії замість сторінки. що це означає, що будь-які шляхи на включеному JavaScript будуть відносно поточного документа.
Tom Carchrae

23

Я усвідомлюю, що тут трохи запізнююся (на 5 років чи більше), але, думаю, є краща відповідь, ніж прийнята, наступним чином:

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

getScript()Функція фактично запобігає кешування в браузері . Якщо ви запустите трасування, ви побачите, що сценарій завантажений URL-адресою, що містить параметр часової позначки:

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

Якщо користувач натискає #addCommentпосилання кілька разів,tinymce.js він буде повторно завантажений з іншої URL-адреси, що позначається часом. Це перемагає мету кешування браузера.

===

Крім того, в getScript()документації є деякий зразок коду, який демонструє, як увімкнути кешування, створивши власну cachedScript()функцію наступним чином:

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

===

Або, якщо ви хочете глобально відключити кешування, ви можете зробити це, використовуючи ajaxSetup()наступне:

$.ajaxSetup({
    cache: true
});

Можливо, це було недоступно, коли ви писали це, але зауважте, що jQuery дозволяє (у всьому світі) відключити цю функцію без кешування та дозволити кешування знову. Дивіться api.jquery.com/jQuery.getScript/#caching-requests (О, я бачу, підхід $ .ajax (), який ви охоплюєте тут, також згадується.)
Пітер Хансен

@PeterHansen - Дякую за пораду. Я оновив свою відповідь вашою пропозицією.
дата

3
Підтримка jQuery 1.12.0 або пізнішої версії вимикає вбудований антикашлін таким чином:$.getScript({url: "test.js",cache:true})
oriadam
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.