Динамическое подключение jQuery
С целью дальнейшего развития моего сервиса-скрипта Share42.com я искал способ динамического подключения фреймворка jQuery непосредственно в коде JavaScript.
Нашел красивое решение, которое выполняет одновременно 2 задачи:
- Проверяет, подключен ли уже на странице jQuery.
- Если не подключен, то подключает его с Гугла.
Таким образом, предотвращается двойная загрузка jQuery на странице, и, соответственно, экономится трафик, если jQuery на сайте уже подключен.
Код скрипта, который реализует вышесказанное, выглядит следующим образом:
var jQ = false;
function initJQ() {
if (typeof(jQuery) == 'undefined') {
if (!jQ) {
jQ = true;
document.write('<scr' + 'ipt type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></scr' + 'ipt>');
}
setTimeout('initJQ()', 50);
} else {
(function($) {
$(function() {
// здесь пишем jQuery код
})
})(jQuery)
}
}
initJQ();
Благодаря этому скрипту, у меня теперь появилась возможность прикрутить к Share42.com функцию сокращения ссылки, которую просят пользователи, а также можно реализовать и вариант с плавающей панелью.
* * *
Профессиональное рекламное агентство полного цикла Промолидер предоставляет весь спектр рекламных услуг, связанных как с изготовлением рекламной продукции, так и непосредственной рекламой товаров и услуг.
Комментарии (58)
Если не ошибаюсь, этот код с одного из постов хабра. Я тоже брал оттуда, но потом переделал под себя, чтобы можно было загружать не только js, но и css… Кстати, на themeforest.net видел отличную технику, когда js и css (например, плагины к jquery) подгружаются только тогда, когда они нужны.
Нет, не с Хабра. Я подобные штуки, как правило, в зарубежном Инете ищу.
Может, лучше так?
Потом в теле скрипта написать myJQuery = getJQuery(); и быть уверенным, что в переменной myJQuery (которую, кстати, можно и $ обозвать при желании) уже находится jQuery?
Я такой вариант пробовал, но у меня он не заработал. Видимо, не все правильно сделал. Если он короче варианта из моего поста, тогда можно будет использовать. Спасибо за комментарий.
Приведите, пожалуйста, пример непосредственно с jQuery кодом. У меня почему-то не работает.
А для чего используется такое разделение:
Так и думал, что кто-то об этом спросит =)
Сказать точно “для чего” я не могу, т.к. в таких делах я не спец, но факт в том, что если так не разделять, то скрипт не сработает, и на экран выведется хтмл-код тега script.
Все банально – если браузер наткнетса на … – то он так и распарсит. Несмотря на то что код находится внути скрипта.
форма съела
А вот не станет ли этот скрипт грузить jQuery повторно, если он уже есть в кэше браузера? По-моему, совершенно ненужный велосипед. Если ты изначально ставишь в link ссылку на гугловское хранилище фреймворка, оно лучше отработать должно. Хотя я не специалист, но размышления меня приводят к такому выводу.
Не станет.
Для тебя может и велосипед, а для меня – решение конкретной задачи.
Суть в том, что на чужом сайте подключается мой скрипт социальных сервисов, и я заранее не знаю, подключает ли jQuery владелец сайта. А вышеобозначенным скриптом как раз и проверю.
Ясно теперь. Извини, сразу не понял суть задачи.
В нормальном браузере не станет, вроде. Браузер проверяет сначала саму ссылку, если она в кэше, затем время изменения файла и прочее, если все идентично кэшу, то файл по ссылке не грузится. Думаю сейчас уже все браузеры так работают. А вот если вреймворк на сайте уже подключен, причем не с гугл-хранилища, без такой проверки библиотека будет грузиться повторно.
С другой стороны, если этот код вызван до того, как подключается jquery локально, то в любом случае библиотека будет загружена 2 раза, или я что-то не так понял?
А еще, Дим зачем нужно такое пугающее зацикливание на каждые 50 миллисекунд: setTimeout(‘initJQ()’, 50);? Оно ведь, ко всему прочему, вроде, еще и бесконечное – опасный код какой-то (так он чего доброго браузер повесит), я его не тестировал, но выглядит опасно :)
Мне кажется, было бы логично, если это вообще возможно, проверять наличие библиотеки jquery сразу после того как загружена head часть документа (ведь, библиотека вызывается почти всегда именно там). Если jquery не обнаружено, то подключать её. Но опять же, кажется, могут возникнуть глюки в разных браузерах.
Верно, если этот код будет вызван ранее чужого и чужой не шарит подобной проверки :)
Бесконечным оно действительно может быть, но не всегда, а только до момента загрузки и выполнения кода jQuery, но всётаки может – если нет доступа к хосту с сорсом или с неверным урлом к сорсу. Тем не менее, не должно вызвать особой нагрузки на браузер – простой if раз в 50мс – это несложно.
Ааа, точно! Но все равно чет не понятно, зачем зацикливать нужно.
Да, скорее всего так и есть.
Ты думаешь, я в этом разбираюсь? =) То, что нашел в Инете, то и вставил.
Я вот если честно так и не понял, что хорошего в этом…
Дима, а в твоем случае, просто вот так разве не будет работать:
Завтра протестирую.
Не используйте document.write – это может плохо кончится :)
Проверил – не работает.
И чем же?
Хотя бы тем что если вы вызовете этот скрипт динамически после загрузки страницы, то браузер заменит содержание страницы на содержимое из document.write
Не заменит, я проверял. Хоть я и ожидал, что заменит, но все в порядке. Пробовал ставить скрипт и в head, и в body.
Dimox, смотрите ниже – любой вызов document.write после загрузки document приведет к обновлению страницы.
Чтобы было понятнее на примере jQuery (чтобы кода меньше):
$(document).ready(function() {
document.write(‘Auch!!’);
});
$(window).load(function() {
document.write(‘Auch!’);
});
А если у меня уже подключён MooTools, который так же использует доллар $ для получения объектов из DOM и тут твой скрипт поверх подгрузит jQuery?
Да. Скрипт же проверяет только наличие jQuery.
var $j = jQuery.noConflict();
$j.function();
разграничивает ваш скрипт от действий иных фреймворков – Мутулз не Мутулз
Смело можно заносить ваш код – вы меня простите – на сайт govnokod.ru – кто нибудь догадался проверить как загрузка вашего кода играет на скорость сайта, задержка в 50 мс в добавок.
Меня всегда удивляло как гадкий код берется с одного левого сайта – где умельцы в кавычках стряпают их мегатоннами и потом такие же умельцы распространяют их повсеместо, в добавок надо сказать этот код не будет работать если на сайте есть еще фреймворки – допустим prototype.js – весь джеквери отпадет – jQuery.noConflict() не учтен – еще надо сказать что оптимально использовать window.onload для асинхронной загрузки скрипта что в разы увеличит скорость – без таймаутов.
Покажите тогда правильную реализацию.
вот так будет выглядеть оптимальная по всем параметрам загрузка джеквери:
(function() {
var jQuery;
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.4.4') {
var script_tag = document.createElement('script');
script_tag.setAttribute("type","text/javascript");
script_tag.setAttribute("src","jquery.min.js");
script_tag.onload = scriptLoadHandler;
script_tag.onreadystatechange = function () { // IE
if (this.readyState == 'complete' || this.readyState == 'loaded') {
scriptLoadHandler();
}
};
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
// Версия jQuery которую мы загружаем для сайта единственна
$ = window.jQuery;
main();
}
/******** Запустить мгновенно после загрузки jQuery ******/
function scriptLoadHandler() {
// Восстановим $ и window.jQuery к первоначальному виду
$ = window.jQuery.noConflict(true);
// Главная функция
main();
}
function main() {
// Здесь наши jQuery дела
}
})();
Спасибо. Завтра потестирую.
Проверил, все замечательно. Большое спасибо! Значит не зря я пост писал =)
Может и не зря и для себя что-то откроете, но вот пару моментов по скрипту выше:
1) если вызов этого скрипта будет перед кодом для библиотек использующих $ в качестве глобальной переменной, то код перестанет работать, так как $ будет перезаписан на объект jQuery.
2) при таком условии (при такой проверке) вы рискуете загрузить версию старше или новее чем уже имеется на сайте – что приведет к потенциальным проблемам
3) где будет задействованна переменная var jQuery из начала скрипта?
Скрипт на коленке похоже писался, а вы его для сервиса собираете использовать…
Может быть тогда предложите свой вариант, лишенный этих недостатков?
Вот немного модифицированный пример. Должен работать в 98% случаев. Но мне кажется что вы себе неправильную задачу поставили. Зачем вам jquery?
Глядя на размер скрипта что-то пропадает желание его использовать =)
Чтобы реализовать функции, которые я не смогу сделать через нативный JavaScript, т.к. не разбираюсь в нем.
Скрипт всегда можно ужать.
К сожалению, в IE скрипт спотыкается на каждом шагу… Кроме того, как насчет случаев, когда jQuery подключается в одном файле, нужная нам функция находится во внешнем файле, а вызывается в третьем (в нужном месте страницы)? (вариантов перенести все в одно место не предлагать)
Вы правы, нужна другая реализация для ИЕ. Сегодня выложу другой вариант. Насчет случаев с подключениями то проблем быть не должно. Если в вашем случае не так пожалуйста проясните.
UPD: Решение (если оно есть) откладывается на пару дней.
Да я знаю про это. Просто я ожидал, что задача решается совсем небольшим скриптом, а оказывается, что все гораздо сложнее.
А почему бы вам не предоставлять услуги в iframe?
засовываете в отдельный js файл после него можно подключать иные фреймворки без страха что они не смогут все вместе работать и все.
по вопросам как работает код пишите отвечу всем – там все просто
Спасибо за статью. Давно хотел знать как правильно работать с квери
Dimox, немного в оффтоп (т.к. гостевой книги тут не нашел, куда ещё писать такой оффтоп незнаю) : твой блог на каком движке крутиться ? MaxSite ?
Через форму обратной связи, вверху ссылка “Контакты”.
Если бы ты заглянул в код страницы, то понял бы, что WordPress =)
ммда, нехило я затупил … даже стыдно стало
У вас такой удобных блог, и столько инфы. Почему я раньше его не встречал?
Наверное, ходили не теми дорогами Интернета =)
а что это за плгин на этом блоге для Подсветка кода? а то я себе искал нашол yntaxHighlighter Plus. Так там галимо то что когда хочеш скопировать код выделяеються и числа строк вместе с кодом…
CodeColorer.