Jak osadzić widżet Javascript, który zależy od jQuery w nieznanym środowisku
Rozwijam widżet javascript, który zależy od jQuery. Widżet może zostać załadowany lub nie na stronę, na której jest już załadowany jQuery. Istnieje wiele problemów, które pojawiają się w tym przypadku...
Jeśli strona nie ma jQuery, muszę załadować własny jQuery. Wydaje się jednak, że jest to delikatna kwestia czasu. Na przykład, jeśli mój widżet ładuje się i wykonuje przed zakończeniem ładowania i wykonywania jQuery, dostaję
jQuery is not defined
błąd.Jeśli strona ma jQuery, zazwyczaj mogę z nią pracować. Jeśli jednak wersja jQuery jest stara, chciałbym załadować własną. Jeśli jednak załaduję własną, muszę to zrobić w taki sposób, aby nie deptać ich zmiennej
$
. Jeśli ustawiłemjQuery.noConflict()
i któryś z ich skryptów zależy od$
, to właśnie złamałem ich stronę.Jeśli strona używa innej biblioteki javascript (np. prototype), musiałem być wrażliwy na zmienną
$
prototype również.
Z powodu wszystkich powyższych, wydaje się, że łatwiej jest nie polegać na jQuery. Ale zanim pójdę w dół tej drogi, która będzie obejmować głównie przepisywanie mojego kodu widget, chciałem poprosić o radę pierwszy.
Podstawowy szkielet mojego kodu, w tym błąd pomiaru czasu i czasami błędy $
, następuje:
<script type="text/javascript" charset="utf-8">
// <![CDATA
if (typeof jQuery === 'undefined') {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = '{{ URL }}/jquery.js';
head.appendChild(script);
}
// ]]>
</script>
<script type="text/javascript" src="{{ URL }}/widget.js"></script>
Mój widget ma następującą strukturę:
(function($) {
var mywidget = {
init: function() {
...
}
};
$(document).ready(function() {
mywidget.init();
});
})(jQuery);
Jeśli istnieją jakieś wskaźniki lub zasoby do osiągnięcia widżetu, który może działać we wszystkich wymienionych środowiska, byliby bardzo mile widziani.
7 answers
Po przejrzeniu kilku odpowiedzi i wskazówek i znalezieniu pomocnych hakerów jQuery, skończyłem z czymś takim:
(function(window, document, version, callback) {
var j, d;
var loaded = false;
if (!(j = window.jQuery) || version > j.fn.jquery || callback(j, loaded)) {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "/media/jquery.js";
script.onload = script.onreadystatechange = function() {
if (!loaded && (!(d = this.readyState) || d == "loaded" || d == "complete")) {
callback((j = window.jQuery).noConflict(1), loaded = true);
j(script).remove();
}
};
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script);
}
})(window, document, "1.3", function($, jquery_loaded) {
// Widget code here
});
Spowoduje załadowanie jQuery, jeśli nie jest już załadowany i zamknie go w wywołaniu zwrotnym, aby nie był sprzeczny z istniejącym wcześniej jQuery na stronie. Sprawdza również, czy dostępna jest minimalna wersja lub wczytuje znaną wersję-w tym przypadku v1.3. Wysyła wartość logiczną do wywołania zwrotnego (mój widget), czy jQuery został załadowany, czy nie na wypadek, gdyby potrzebne były jakieś wyzwalacze. I dopiero po załadowaniu jQuery wywołuje mój widget, przekazując do niego jQuery.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-28 19:03:57
Zobacz Jak zbudować widget www (używając jQuery) by Alex Marandon.
(function() {
// Localize jQuery variable
var jQuery;
/******** Load jQuery if not present *********/
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.4.2') {
var script_tag = document.createElement('script');
script_tag.setAttribute("type","text/javascript");
script_tag.setAttribute("src",
"http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js");
if (script_tag.readyState) {
script_tag.onreadystatechange = function () { // For old versions of IE
if (this.readyState == 'complete' || this.readyState == 'loaded') {
scriptLoadHandler();
}
};
} else { // Other browsers
script_tag.onload = scriptLoadHandler;
}
// Try to find the head, otherwise default to the documentElement
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
// The jQuery version on the window is the one we want to use
jQuery = window.jQuery;
main();
}
/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
// Restore $ and window.jQuery to their previous values and store the
// new jQuery in our local jQuery variable
jQuery = window.jQuery.noConflict(true);
// Call our main function
main();
}
/******** Our main function ********/
function main() {
jQuery(document).ready(function($) {
// We can use jQuery 1.4.2 here
});
}
})(); // We call our anonymous function immediately
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-11 00:54:03
Co zrobić, jeśli chcesz również użyć niektórych wtyczek jQuery? Czy można zrobić sobie pojedynczy plik z minifikowanymi wersjami wtyczek, a także załadować te, jak poniżej? (Załadowany z S3, w tym konkretnym przykładzie.)
(function(window, document, version, callback) {
var j, d;
var loaded = false;
if (!(j = window.jQuery) || version > j.fn.jquery || callback(j, loaded)) {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js";
script.onload = script.onreadystatechange = function() {
if (!loaded && (!(d = this.readyState) || d == "loaded" || d == "complete")) {
window.jQuery.getScript('http://mydomain.s3.amazonaws.com/assets/jquery-plugins.js', function() {
callback((j = window.jQuery).noConflict(1), loaded = true);
j(script).remove();
});
}
};
document.documentElement.childNodes[0].appendChild(script)
}
})(window, document, "1.5.2", function($, jquery_loaded) {
// widget code goes here
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-19 22:13:46
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:30:50
Czy można użyć dokumentu.write() aby opcjonalnie dodać skrypt jQuery do strony? To powinno zmusić jQuery do synchronicznego ładowania. Spróbuj tego:
<script type="text/javascript" charset="utf-8">
// <![CDATA
if (typeof jQuery === 'undefined') {
document.write('<script src="{{ URL }}/jquery.js"><' + '/script>');
}
// ]]>
</script>
<script type="text/javascript" src="{{ URL }}/widget.js"></script>
Jeśli chcesz zrobić jQuery sprawdzić wewnątrz skryptu widget następnie wierzę, że następujące działa cross-browser:
(function() {
function your_call($) {
// your widget code goes here
}
if (typeof jQuery !== 'undefined') your_call(jQuery);
else {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = '{{ URL }}/jquery.js';
var onload = function() {
if (!script.readyState || script.readyState === "complete") your_call(jQuery);
}
if ("onreadystatechange" in script) script.onreadystatechange = onload;
else script.onload = onload;
head.appendChild(script);
}
})()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-31 11:01:22
Wiem, że to stary temat... ale mam coś szybszego niż twój hack. Spróbuj w widgecie
"init": function()
To naprawi problem
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-05 07:22:49
Pobrałbym źródło jQuery i zmodyfikował obiekt jQuery na inny (jQueryCustom).
A następnie znajdź instancję, która ustawia symbol {[2] } jako obiekt jQuery i skomentuj tę procedurę.
Nie wiem, czy to łatwe czy trudne, ale na pewno spróbuję.(Sprawdź również drugą opcję, ponieważ nie jest źle, strona, na której będzie wykonywany widget, może mieć wersję jQuery starszą niż ta, której potrzebujesz).
EDIT: ja tylko sprawdziłem źródło. Wystarczy zastąpić jQuery
innym ciągiem znaków (jQcustom
na przykład). Następnie spróbuj skomentować ten wiersz:
_$ = window.$
I odwołujesz się do niestandardowego jQuery tak:
jQcustom("#id").attr(...)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-31 03:32:22