javascript - mostrar - Posible diferir la carga de jQuery?
jquery change title (15)
Agrego este fragmento de código después de la etiqueta de secuencia de comandos de jquery asincrónico / diferido, esto define una función $ temporal que acumulará lo que sea necesario ejecutar cuando todo se haya cargado, y luego, una vez que hayamos terminado de usar $ esa vez Se sobreescribiría para ejecutar las funciones. Con este fragmento de código no es necesario cambiar la sintaxis de carga de jQuery más abajo en el documento.
<script defer async src="https://code.jquery.com/jquery-2.2.0.min.js">
<script>
var executeLater = [];
function $(func) {
executeLater.push(func);
}
window.addEventListener(''load'', function () {
$(function () {
for (var c = 0; c < executeLater.length; c++) {
executeLater[c]();
}
});
})
</script>
....y entonces...
<script>
$(function() {
alert("loaded");
});
</script>
Seamos realistas, jQuery / jQuery-ui es una descarga pesada.
Google recomienda la carga diferida de JavaScript para acelerar la representación inicial. Mi página usa jQuery para configurar algunas pestañas que están ubicadas en la parte inferior de la página (en su mayoría fuera de la vista inicial) y me gustaría diferir jQuery hasta DESPUÉS de que la página se haya procesado.
El código de aplazamiento de Google agrega una etiqueta al DOM después de que la página se cargue al enganchar en el cuerpo en el evento de carga:
<script type="text/javascript">
// Add a script element as a child of the body
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "deferredfunctions.js";
document.body.appendChild(element);
}
// Check for browser support of event handling capability
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
Me gustaría aplazar la carga de jQuery de esta manera, pero cuando lo probé, mi código de jQuery no pudo encontrar jQuery (no completamente inesperado por mi parte):
$(document).ready(function() {
$("#tabs").tabs();
});
Por lo tanto, parece que necesito encontrar una forma de diferir la ejecución de mi código jQuery hasta que se cargue jQuery. ¿Cómo detecto que la etiqueta agregada ha terminado de cargarse y analizarse?
Como corolario, parece que la carga asíncrona también puede contener una respuesta.
¿Alguna idea?
Aquí está mi versión que admite el encadenamiento para estar seguros de que los scripts se cargan uno tras otro, según el código de ampersand :
var deferredJSFiles = [''jquery/jquery'', ''file1'', ''file2'', ''file3''];
function downloadJSAtOnload() {
if (!deferredJSFiles.length)
return;
var deferredJSFile = deferredJSFiles.shift();
var element = document.createElement(''script'');
element.src = deferredJSFile.indexOf(''http'') == 0 ? deferredJSFile : ''/js/'' + deferredJSFile + ''.js'';
element.onload = element.onreadystatechange = function() {
if (!this.readyState || this.readyState == ''loaded'' || this.readyState == ''complete'')
downloadJSAtOnload();
};
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener(''load'', downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent(''onload'', downloadJSAtOnload);
else
window.onload = downloadJSAtOnload;
Aquí hay una buena descripción del enfoque moderno para la carga de JavaScript asíncrona / diferida . Pero no funciona para scripts en línea
<script type="text/javascript" src="/jquery/3.1.1-1/jquery.min.js" defer></script>
<script type="text/javascript" defer>
$(function () { // <- jquery is not yet initialized
...
});
</script>
La solución más simple para la carga asíncrona fue sugerida por @nilskp - externalizar script:
<script type="text/javascript" src="/jquery/3.1.1-1/jquery.min.js" defer></script>
<script type="text/javascript" src="resources/js/onload.js" defer></script>
Bueno, me parece que todo lo que tiene que hacer es a) agregar el código jQuery que desea ejecutar durante la carga, al final del archivo jQuery o b) agregarlo a la función downloadJSAtOnload
manera:
<script type="text/javascript">
// Add a script element as a child of the body
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "deferredfunctions.js";
document.body.appendChild(element);
$("#tabs").tabs(); // <==== NOTE THIS. This should theoretically run after the
// script has been appended, though you''ll have to test this
// because I don''t know if the JavaScript above will wait for
// the script to load before continuing
}
// Check for browser support of event handling capability
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
Cargue todos los scripts al final de html con http://labjs.com , es una solución al 100% y lo probé muchas veces contra las reglas de gtmetrix. ejemplo http://gtmetrix.com/reports/interactio.cz/jxomHSLV
Coloque jQuery y su código dependiente de jQuery al final de su archivo HTML.
Edit: un poco más claro
<html>
<head></head>
<body>
<!-- Your normal content here -->
<script type="text/javascript" src="http://path/to/jquery/jquery.min.js"></script>
<script>//Put your jQuery code here</script>
</body>
</html>
Creo que vale la pena mencionar Modernizr.load (): maneja la dependencia de carga muy bien
Dado que esta es una pregunta de primer nivel en un tema importante, permítame ser tan audaz para proporcionar mi propia opinión sobre esto basada en una respuesta anterior de @valmarv y @amparsand.
Estoy usando una matriz multidimensional para cargar los scripts. Agrupando a los que no tienen dependencias entre ellos:
var dfLoadStatus = 0;
var dfLoadFiles = [
["http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"],
["http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js",
"/js/somespecial.js",
"/js/feedback-widget.js#2312195",
"/js/nohover.js"]
];
function downloadJSAtOnload() {
if (!dfLoadFiles.length) return;
var dfGroup = dfLoadFiles.shift();
dfLoadStatus = 0;
for(var i = 0; i<dfGroup.length; i++) {
dfLoadStatus++;
var element = document.createElement(''script'');
element.src = dfGroup[i];
element.onload = element.onreadystatechange = function() {
if ( ! this.readyState ||
this.readyState == ''complete'') {
dfLoadStatus--;
if (dfLoadStatus==0) downloadJSAtOnload();
}
};
document.body.appendChild(element);
}
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
Carga el primer jQuery una vez que se carga, continúa cargando los otros scripts a la vez. Puede agregar scripts fácilmente agregando a la matriz en cualquier lugar de su página:
dfLoadFiles.push(["/js/loadbeforeA.js"]);
dfLoadFiles.push(["/js/javascriptA.js", "/js/javascriptB.js"]);
dfLoadFiles.push(["/js/loadafterB.js"]);
Echa un vistazo a jQuery.holdReady()
"Retiene o libera la ejecución del evento de jQuery ready". (jQuery 1.6+)
El siguiente código debería cargar sus scripts una vez que la ventana haya terminado de cargarse:
<html>
<head>
<script>
var jQueryLoaded = false;
function test() {
var myScript = document.createElement(''script'');
myScript.type = ''text/javascript'';
myScript.async = true;
myScript.src = jQueryLoaded ? ''http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js'' : ''http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js'';
document.body.appendChild(myScript);
if(!jQueryLoaded){
alert(''jquery was loaded'');
jQueryLoaded = true;
test();
} else {
alert(''jqueryui was loaded'');
}
}
if (window.addEventListener){
alert(''window.addEventListener'');
window.addEventListener("load", test, false);
} else if (window.attachEvent){
alert(''window.attachEvent'');
window.attachEvent("onload", test);
} else{
alert(''window.onload'');
window.onload = test;
}
</script>
</head>
<body>
<p>Placeholder text goes here</p>
</body>
</html>
Me funcionó en Chrome, FF e IE9; avíseme si eso ayuda.
En cierta situación, podría disparar un evento cuando se carga jquery.
<script type="text/javascript">
(function (window) {
window.jQueryHasLoaded = false;
document.body.addEventListener(''jqueryloaded'', function (e) {
console.log(''jqueryloaded '' + new Date() );
}, false);
function appendScript(script) {
var tagS = document.createElement("script"),
s = document.getElementsByTagName("script")[0];
tagS.src = script.src;
s.parentNode.insertBefore(tagS, s);
if ( script.id == ''jquery'' ) {
tagS.addEventListener(''load'', function (e) {
window.jQueryHasLoaded = true;
var jQueryLoaded = new Event(''jqueryloaded'');
document.body.dispatchEvent(jQueryLoaded);
}, false);
}
}
var scripts = [
{
''id'': ''jquery'',
''src'': ''js/libs/jquery/jquery-2.0.3.min.js''
},
{
''src'': ''js/myscript1.js''
},
{
''src'': ''js/myscript2.js''
}
];
for (var i=0; i < scripts.length; i++) {
appendScript(scripts[i]);
}
}(window));
</script>
Luego envuelve tus dependencias en una función:
// myscript1.js
(function(){
function initMyjQueryDependency() {
console.log(''my code is executed after jquery is loaded!'');
// here my code that depends on jquery
}
if ( jQueryHasLoaded === true )
initMyjQueryDependency();
else
document.body.addEventListener(''jqueryloaded'', initMyjQueryDependency, false);
}());
Si jquery termina de cargarse después de los otros scripts, sus dependencias se ejecutarán cuando se dispare el evento jqueryloaded.
Si jquery ya está cargado, jQueryHasLoaded === true
, su dependencia se ejecutará initMyjQueryDependency()
.
Parece que solo necesita <script defer>
: http://www.w3schools.com/tags/att_script_defer.asp
Prueba esto, que es algo que edité hace un tiempo desde el bookmarklet jQuerify. Lo uso con frecuencia para cargar jQuery y ejecutar cosas después de que se cargue. Por supuesto, puede reemplazar la url allí con su propia url para su jquery personalizado.
(function() {
function getScript(url,success){
var script=document.createElement(''script'');
script.src=url;
var head=document.getElementsByTagName(''head'')[0],
done=false;
script.onload=script.onreadystatechange = function(){
if ( !done && (!this.readyState || this.readyState == ''loaded'' || this.readyState == ''complete'') ) {
done=true;
success();
script.onload = script.onreadystatechange = null;
head.removeChild(script);
}
};
head.appendChild(script);
}
getScript(''http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js'',function(){
// YOUR CODE GOES HERE AND IS EXECUTED AFTER JQUERY LOADS
});
})();
Realmente combinaría jQuery y jQuery-UI en un archivo y utilizaría una URL para ello. Si REALMENTE desea cargarlos por separado, simplemente encadene los getScripts:
getScript(''http://myurltojquery.js'',function(){
getScript(''http://myurltojqueryUI.js'',function(){
//your tab code here
})
});
<!doctype html>
<html>
<head>
</head>
<body>
<p>If you click on the "Hide" button, I will disappear.</p>
<button id="hide" >Hide</button>
<button id="show" >Show</button>
<script type="text/javascript">
function loadScript(url, callback) {
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState) { //IE
script.onreadystatechange = function() {
if (script.readyState == "loaded" ||
script.readyState == "complete") {
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function() {
callback();
};
}
script.src = url;
document.body.appendChild(script);
}
loadScript("http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js",
function() {
//YAHOO.namespace("mystuff");
$("#show").click(function() {
$("p").show();
});
$("#hide").click(function() {
$("p").hide();
});
//more...
});
</script>
</body>
</html>
element.addEventListener("load", function () {
$(''#tabs'').tabs()
}, false);
Trata eso.