Загрузка jQuery по требованию

- Posted in Webdev by - Permalink

Оригинал: Load jQuery on demand | Web-developer notepad

Для загрузки jQuery по требованию вы можете пользоваться скриптом loadJquery.js.

Быстрый старт

Загрузите скрипт по этой ссылке, отредактируйте его нижнюю часть после слов PUT YOUR CODE HERE, вот эту:

(function () {
...
    /* PUT YOUR CODE HERE  */
    loadJquery({
        url: 'http://code.jquery.com/jquery-latest.min.js',
        timeout: 5000, //ms
        success: function ($) {
            $('h1').css('border', '2px solid red');
        },
        error: function () {
            alert("Can't load jQuery.");
        }
    });
}());

Преимущества скрипта:

  • кроссбраузерность
  • основан на коде jquery 1.7.2
  • отлов исключений при помощи try/catch
  • возможность указания таймаута загрузки
  • загрузка не будет производиться, если jQuery уже загружен.
  • простота использования для конечного пользователя: просто пишите свой код в success/error-колбеки
  • отсутствие конфликтов с другими js-библиотеками типа prototype.js
  • скрипт проходит jslint-валидацию

Теперь больше информации для тех, кто хочет узнать подробности.

Скрипт состоит из двух частей: loadScript и loadJquery.

loadScript

Функция практически полностью сделана на основе кода jQuery 1.7.2, актуальной в данный момент. Загрузка скрипта производится посредством добавления тега script в head. Производится контроль исключений при помощи try/catch, теоретически не должно быть никаких ошибок яваскрипта. Предусмотрена возможность указания тайм-аута, по достижению которого будет вызван error-callback.

Пример использования.

loadScript({
    url: 'http://example.com/script.js', //script url
    timeout: 5000, //optional timeout in ms
    success: function () {
        alert('Script loaded callback.');
    },
    error: function () {
        alert('Script was not loaded.');
    }
});

loadJquery

Особенности функции loadJquery следующие:

  • загрузка jQuery не будет производиться, если jQuery уже загружен
  • используется .noConflict(), т.е. можно не беспокоиться о возникновении конфликтов с другой библиотекой типа prototype.js

Полный листинг скрипта

/*!
 *
 * loadJquery.js
 * Load jQuery on demand from javascript
 * Author: contact@slicezilla.com
 * November 2011
 *
 * The script uses part of jQuery JavaScript Library v1.7
 * http://jquery.com/
 * Copyright 2011, John Resig
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
*/
/*global document, setTimeout, clearTimeout, alert, jQuery*/
(function () {
    "use strict";
    var loadScript = function (options) {
        var script, transportTimeout,
            head = document.head || document.getElementsByTagName('head')[0] || document.documentElement,
            transport = {
                send: function (url, successCallback) {
                    script = document.createElement('script');
                    script.async = 'async';
                    script.src = url;
                    // Attach handlers for all browsers
                    script.onload = script.onreadystatechange = function (event, isAbort) {
                        if (isAbort || !script.readyState || /loaded|complete/.test(script.readyState)) {
                            // Handle memory leak in IE
                            script.onload = script.onreadystatechange = null;
                            // Remove the script
                            if (head && script.parentNode) {
                                head.removeChild(script);
                            }
                            // Dereference the script
                            script = undefined;
                            //callback if not abort
                            if (!isAbort && typeof successCallback === 'function') {
                                clearTimeout(transportTimeout);
                                successCallback();
                            }
                        }
                    };
                    // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
                    // This arises when a base node is used (#2709 and #4378).
                    head.insertBefore(script, head.firstChild);
                    //head.appendChild(script);
                },
                abort: function (errorCallback) {
                    clearTimeout(transportTimeout);
                    if (script) {
                        script.onload(0, 1);
                    }
                    if (typeof errorCallback === 'function') {
                        errorCallback();
                    }
                }
            };
        //init timeout
        if (options.timeout > 0) {
            transportTimeout = setTimeout(function () {
                transport.abort(options.error);
            }, options.timeout);
        }
        //get script
        try {
            transport.send(options.url, options.success);
        } catch (e) {
            transport.abort(options.error);
        }
    };
    //function which will load jQuery using loadScript
    function loadJquery(options) {
        if (typeof jQuery !== 'undefined') {
            //jQuery is loaded already, just perform business logic
            if (typeof options.success === 'function') {
                //pass jQuery as parameter, in order to have $ === jQuery in callback
                //just in case that $.noConflict was used already, and $ !== jQuery
                jQuery(options.success);
            }
        } else {
            //jQuery was not loaded on a page
            loadScript({
                url: options.url,
                timeout: options.timeout,
                success: function () {
                    jQuery.noConflict();
                    if (typeof options.success === 'function') {
                        jQuery(options.success);
                    }
                },
                error: options.error
            });
        }
    }
    /* -------- PUT YOUR CODE HERE -------- */
    loadJquery({
        url: 'http://code.jquery.com/jquery-latest.min.js',
        timeout: 5000, //ms
        success: function ($) {
            $('h1').css('border', '2px solid red');
        },
        error: function () {
            alert("Can't load jQuery.");
        }
    });
}());

Обсудить