que - llamar javascript desde html
¿Cuándo se ejecuta exactamente la devolución de llamada $(documento).ready? (6)
Supongamos que adjuntamos un controlador .click()
a una etiqueta de anclaje ( <a>
) en la devolución de llamada $(document).ready
. Este controlador cancelará la acción predeterminada (siguiendo el href
) y mostrará una alerta.
Lo que me gustaría saber es cuándo exactamente se ejecutará la devolución de llamada y si es posible que el usuario haga clic en el delimitador (el documento se ha mostrado en el navegador) pero el evento aún no se ha conectado.
Aquí hay diferentes páginas HTML que contienen un ancla pero el orden de inclusión de las secuencias de comandos es diferente. ¿Cuál es la diferencia (si hay alguna) entre ellos? ¿Los diferentes navegadores se comportarán de manera diferente?
Página 1:
<html>
<head>
<title>Test 1</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
$(''a'').click(function() {
alert(''overriding the default action'');
return false;
});
});
</script>
</head>
<body>
<a href="http://www.google.com">Test</a>
</body>
</html>
Página 2:
<html>
<head>
<title>Test 1</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
</head>
<body>
<a href="http://www.google.com">Test</a>
<script type="text/javascript">
$(function() {
$(''a'').click(function() {
alert(''overriding the default action'');
return false;
});
});
</script>
</body>
</html>
Página 3:
<html>
<head>
<title>Test 1</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<a href="http://www.google.com">Test</a>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
$(''a'').click(function() {
alert(''overriding the default action'');
return false;
});
});
</script>
</body>
</html>
Entonces, ¿es posible que un usuario sea redireccionado al href
haciendo clic en el ancla y nunca vea la alerta (ignorando el caso de javascript desactivado, por supuesto)? ¿Podría suceder esto en cualquiera de los ejemplos que proporcioné?
Todo lo que necesito es asegurarme de que el controlador de eventos click
se haya adjuntado al anclaje antes de que el usuario tenga la posibilidad de hacer clic en este anclaje. Sé que puedo proporcionar un href
vacío y luego mejorarlo progresivamente en javascript, pero esta es una pregunta más general.
¿Qué sucederá en caso de que el HTML sea generado rápidamente por el servidor web, pero la biblioteca jquery tarda tiempo en ser extraída de un servidor distante? ¿Esto influenciará mi escenario? ¿Cuál es el orden de inclusión de los scripts en comparación con la carga del DOM? ¿Podrían hacerse en paralelo?
Depende de muchas cosas. Si ha fragmentado la codificación, por ejemplo, es posible que un usuario obtenga un fragmento, pero como el documento aún no está listo, el oyente no se adjuntará.
El evento jQuery ready es el evento DOMContentLoaded en navegadores compatibles con W3C (estandarizados en la especificación HTML5) y algunas alternativas de esto en otros (como readystate en IE).
DOMContentLoaded (MDC)
Disparado en el objeto Documento de la página cuando finaliza el análisis del documento. Cuando se dispare este evento, el DOM de la página está listo.
Debido a que esto ocurre antes de la representación, sería una suposición sólida que una devolución de llamada ejecutada después de este evento pueda evitar la interacción del usuario en una página no lista.
Pero como señaló Peter Michaux en su artículo debido a las diferencias de cómo los navegadores implementan este evento, "una técnica robusta para la activación temprana no es posible en los cuatro navegadores principales".
Así que diría que no puedes confiar 100% en el evento jQuery ready, pero la mayoría de las veces funcionará bien.
El ejemplo 3 tendrá la mayor probabilidad de que el usuario pueda hacer clic en el enlace sin que el controlador se haya adjuntado. Dado que está cargando la biblioteca de jQuery después de que se represente el enlace, si los servidores de Google son un poco lentos (o la búsqueda de DNS tarda un segundo más o menos), o la computadora de los usuarios tarda en procesar jQuery, el enlace no tendrá su manejador de clics adjunto cuando el usuario intenta hacer clic en él.
Otra situación donde esto podría suceder es si tiene una página de carga muy grande o lenta y este enlace está en la parte superior. Entonces el DOM puede no estar completamente listo cuando partes de él son visibles. Si te encuentras con un problema como este, lo más seguro es:
- Cargue jQuery en la
head
(ejemplo 1 o 2) - Adjunte el evento click inmediatamente después del elemento
<a>
, pero no en una devolución de llamada DOMReady. De esta forma se llamará de inmediato y no esperará el resto del documento.
Una vez que se representa un elemento, se puede obtener del DOM, y posteriormente jQuery puede acceder a él:
<a href="http://www.google.com">Test</a>
<script type="text/javascript>
// No (document).ready is needed. The element is availible
$(''a'').click(function() {
alert(''overriding the default action'');
return false;
});
</script>
Además, basándose en el comentario de user384915, si la acción depende completamente de JavaScript, entonces ni siquiera lo renderiza como parte del HTML, agréguelo después de que jQuery esté listo:
<script type="text/javascript">
jQuery(function($){
$("<a />", {
style: "cursor: pointer",
click: function() {
alert(''overriding the default action'');
return false;
},
text: "Test"
}).prependTo("body");
});
</script>
En YUI, existen los métodos onContentReady()
y onAvailable()
. desafortunadamente no hay un equivalente a eso en jQuery. Sin embargo, hay un complemento que fue inspirado por ellos:
http://www.thunderguy.com/semicolon/2007/08/14/elementready-jquery-plugin/
Esto debería permitir vincular los eventos al delimitador antes de que el DOM esté completamente cargado.
Por supuesto, es posible "engañar" la advertencia de alerta (incluso si el Javascript está habilitado). Intenta arrastrar el enlace en el campo url y verás que se ejecutará sin esa advertencia. Esto es especialmente problemático si el enlace desencadena la acción de eliminación.
Acerca de la devolución de llamada de document.ready - También tengo ese problema. Dejame explicar. Estamos haciendo un proyecto donde todos los formularios se muestran en ventanas emergentes (ventana de jQuery). Entonces, cuando la ventana emergente está cerrada (por ahora), la página se vuelve a cargar y tuve casos en los que me redireccionaron a otra pantalla en lugar de abrir una nueva ventana emergente.
Totalmente de acuerdo con user384915 sobre poner javascript directamente en el evento onClick o incluso mejor en la etiqueta href.
Su tercer ejemplo proporciona la mayor posibilidad de que el usuario haga clic sin que se haya adjuntado el controlador de anulación. El navegador generalmente descarga y analiza cada <script>
antes de pasar al siguiente. Estás extrayendo jQuery de una fuente externa (Google), que, si bien es confiable, podría no estar disponible o demorarse en cargarse. Tiene los dos bloques <script>
al final de su documento <body>
, por lo que las áreas anteriores de la página probablemente ya se habrán descargado y renderizado en la pantalla mientras se manejan estos dos últimos scripts. Si bien este enfoque se recomienda para presentar una experiencia de carga de página receptiva para el usuario, podrían hacer clic durante este período incierto, y por supuesto, el controlador de reemplazo aún no habría sido adjuntado.
Hay un interesante artículo de YUIblog sobre scripts y orden de carga here .
Tienes un par de preguntas diferentes aquí
¿Cuándo se ejecuta exactamente la devolución de llamada $ (documento) .ready?
Se ejecuta tan pronto como el DOM esté completamente cargado. NO cuando todo (como imágenes) termina de descargarse como lo haría .load (). Es (en general) antes de eso, básicamente es cuando la página se construye.
Lo que me gustaría saber es cuándo exactamente se ejecutará la devolución de llamada
Cuando se hace clic.
es posible que el usuario haga clic en el anclaje (el documento se ha mostrado en el navegador) pero el evento aún no se ha conectado.
Sí, es posible. Pero ponerlo en .ready () te da la mejor posibilidad de que no lo haga. Solo hay 2 formas de hacerlo para estar "más seguro" de que no será así. En realidad, están usando el ''onclick'' en el enlace en sí mismo, y colocando el javascript directamente después del enlace (y no en .ready ()) para que se ejecute inmediatamente después de que se cree el enlace.
Además, no hay diferencia entre cómo funcionarán las 2 muestras de código que proporcionó. Sin embargo, en el segundo no necesita poner el código en .ready (), porque existe después del enlace, siempre se ejecutará después de que se haya creado el enlace. Si lo quitó de .ready () sería la primera de las 2 formas que describí anteriormente.
Además, en lugar de poner ''return false;'' en su devolución de llamada, es mejor usar .preventDefault () y .stopPropagation () esto le permitirá especificar si desea evitar la acción predeterminada o evitar que el evento burbujee, o ambos.