Includi programmaticamente JQuery in un ambiente ad alto conflitto -
-
05-07-2019 - |
Domanda
Sto scrivendo uno snippet di codice da inserire su qualsiasi sito Web di terze parti e NON ho idea in quale ambiente verrà inserito. Il mio obiettivo finale è che il badge sia
<script src="http://example.com/js/badge.js"></script>
Vorrei usare jQuery nel mio codice badge per semplificarmi la vita, ma non voglio richiedere un'altra inclusione sul lato client (ottenere qualcosa di aggiornato sul client è una seccatura).
Questo è il massimo che ho potuto inventare. Non voglio che nulla prima o dopo la mia sceneggiatura venga influenzato da eventuali variabili rimanenti o strane collisioni. Qualcuno ha riscontrato problemi?
(function() {
function main($) {
// do stuff with $
$(document.body).css("background", "black")
}
// If jQuery exists, save it
var old_jQuery = null;
if (typeof(jQuery) != "undefined") {
if (typeof(jQuery.noConflict) == "function") {
old_jQuery = jQuery.noConflict(true);
}
}
var addLibs = function() {
// Body isn't loaded yet
if (typeof(document.body) == "undefined" || document.body === null) {
setTimeout(addLibs, 100);
return;
}
var node = document.createElement("script");
node.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js";
document.body.appendChild(node);
checkLibs();
}
var checkLibs = function() {
// Library isn't done loading
if (typeof(jQuery) == "undefined" || jQuery("*") === null) {
setTimeout(checkLibs, 100);
return;
}
var new_jQuery = jQuery.noConflict(true);
jQuery = old_jQuery;
main(new_jQuery);
}
addLibs();
})();
Soluzione
Ho finito con http://yourock.paulisageek.com/js/popup.js . Vedi il test (con la registrazione della console disponibile) http://paulisageek.com/tmp/jquery-programmatic. html . Non ripristina jQuery e $ fino a quando jQuery non termina effettivamente il caricamento. Un modo per bloccare javascript senza un ciclo infinito (che blocca il caricamento di jQuery stesso)?
// A namespace for all the internal code
var yourock = {};
// Include JQuery programatically
(function() {
// Don't let the script run forever
var attempts = 30;
// If jQuery exists, save it and delete it to know when mine is loaded
var old_jQuery;
if (typeof(jQuery) != "undefined") {
if (typeof(jQuery.noConflict) == "function") {
old_jQuery = jQuery;
delete jQuery;
}
}
var addLibs = function() {
var head = document.getElementsByTagName("head");
if (head.length == 0) {
if (attempts-- > 0) setTimeout(addLibs, 100);
return;
}
var node = document.createElement("script");
node.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js";
head[0].appendChild(node);
checkLibs();
}
var checkLibs = function() {
// Library isn't done loading
if (typeof(jQuery) == "undefined" || typeof(jQuery) != "function" || jQuery("*") === null) {
if (attempts-- > 0) setTimeout(checkLibs, 100);
return;
}
yourock.jQuery = jQuery.noConflict(true);
if (typeof old_jQuery == "undefined")
jQuery = old_jQuery;
}
addLibs();
})();
Altri suggerimenti
Funziona:
(function(){
if (window.jQuery !== undefined) {
doStuff(jQuery);
} else {
var script = document.createElement('script');
script.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js';
document.getElementsByTagName('head')[0].appendChild(script);
var interval = setInterval(function(){
if (window.jQuery) {
clearInterval(interval);
var JQ = jQuery.noConflict(true);
doStuff(JQ);
}
}, 100);
}
})();
function doStuff($) { /* Do stuff with $ */ }
Includere di nuovo jQuery sovrascriverà la variabile $
, che potrebbe essere una versione precedente di jQuery o di un altro framework. Probabilmente dovresti salvarlo anche tu.
Non ho testato così tanto questo codice ma dovrebbe funzionare ...
(function($, window) {
var version = ($ && typeof($) == 'function' && $().jquery ? ($().jquery).split('.').join('') : 0), // 1.8.1 -> 181
jBack = null;
if (version) console.log('jQuery current version : ', version);
else console.log('no jQuery');
var loaded = function() {
console.log('loaded()');
var $ = jQuery.noConflict(true); // LOCAL own jQuery version
if (jBack) {
window.$ = jBack; // Reassign ex-jQuery
window.jQuery = jBack;
}
// OK : now work with OUR new $
console.log('jQuery new version : ', $().jquery);
},
loadJs = function(jsPath) {
console.log('loadJs()');
var s = document.createElement('script');
s.setAttribute('type', 'text/javascript');
s.setAttribute('src', jsPath);
s.onload = loaded;
document.getElementsByTagName('body')[0].appendChild(s);
};
if (version) jBack = $;
if (version < 180) loadJs('http://code.jquery.com/jquery-1.9.1.min.js');
else loaded();
})((typeof(jQuery) == 'function' ? jQuery : null), window);