2012-05-27 13 views
5

Esta pregunta es tan básica, estoy seguro de que debe haber un duplicado de algo, aunque tengo looked for something similar.Javascript: El mejor lugar para registrar controladores de eventos

Mi pregunta es básicamente: ¿Cuál es el mejor lugar para registrar inicialmente controladores de eventos para elementos HTML?

La forma más fácil de registrar un controlador de eventos es, obviamente, sólo lo hacen en línea:

<div id = "mybutton" onclick = "doSomething()">Click me</div> 

Pero esto va en contra de la marcha abrumadora hacia la separación de la lógica y el contenido en el desarrollo web moderno. Entonces, en 2012, se supone que toda la lógica/comportamiento debe hacerse en código JavaScript puro. Eso es genial, y conduce a un código más fácil de mantener. Pero aún necesita un gancho inicial que conecte sus elementos HTML con su código JavaScript.

Por lo general, acabo de hacer algo como:

<body onload = "registerAllEventHandlers()"> 

... Pero eso sigue siendo "trampa", ¿no es así - porque todavía estamos utilizando JavaScript en línea aquí. Pero, ¿qué otras opciones tenemos? No podemos hacerlo en una etiqueta en la sección <script><head>, porque en ese momento no podemos acceder al DOM ya que la página no se ha cargado todavía:

<head> 
<script type = "text/javascript"> 
    var myButton = document.getElementById("mybutton"); // myButton is null! 
</script> 
</head> 

¿Colocamos una etiqueta en la <script>parte inferior de la página o algo? Me gusta:

<html> 
<body> 
... 
... 
<script type = "text/javascript"> 
    registerAllEventHandlers(); 
</script> 
</body> 
</html> 

¿Cuál es la mejor práctica aquí?

Respuesta

2

Puede utilizar window.onload:

<script type = "text/javascript"> 
    window.onload = registerAllEventHandlers; 
</script> 

O si utiliza :

$(registerAllEventHandlers); 

Usando onload obras, ya que registra onload caso de inmediato, pero se dispara cuando DOM está listo.

+0

-1: El evento 'window.onload' no es equivalente al uso del evento' ready' de jQuery: 'window.onload' se activará cuando la página haya terminado de cargarse, incluidos todos los recursos externos (imágenes, CSS, etc.) mientras El evento 'ready' de jQuery se activará una vez que el HTML haya terminado de cargarse pero antes de los recursos externos. Usar 'window.onload' es una mala idea, porque en muchos casos (muchas imágenes, conexión lenta, etc.) los eventos de JavaScript no se registrarán durante mucho tiempo. – georgebrock

+0

@slebetman: ¿Puede explicar por qué es estúpido asociar manejadores de eventos JS antes de que se carguen imágenes (etc.) y comprender las diferencias entre dos técnicas diferentes? En un sitio destinado a aprender y compartir información, un comentario que dice "eso es estúpido" no es muy constructivo. – georgebrock

0

Tenía a similar answer a esto, pero era sobre JavaScript en general. Pero la idea sigue siendo la misma: cargar scripts antes de cerrar el cuerpo.

Aproveche las bibliotecas que resumen el window.onload y el evento listo para DOM. De esta forma, puede cargar los scripts tan pronto como el DOM esté listo.

0

Debe registrar sus controladores de eventos tan pronto como el DOM esté listo. Detectar esto en todos los navegadores no siempre ha sido fácil, aunque con la notable excepción de IE 8 (y anterior) los navegadores más utilizados ahora admiten el evento DOMContentLoaded (gracias a gengkev para señalarlo en los comentarios).

Esto es esencialmente equivalente a llamar a su función registerAllEventHandlers al final de su body, pero tiene la ventaja de que no necesita agregar ningún JavaScript a su HTML.

Es significativamente mejor que usar window.onload porque eso no se ejecuta hasta que se hayan cargado todos los recursos de la página (imágenes, CSS, etc.).

Si está utilizando uno de los principales frameworks de JavaScript, entonces puede detectar fácilmente cuándo el DOM está listo, incluso en versiones anteriores de IE. Con jQuery se usaría el ready event:

jQuery(document).ready(function() { 
    // Your initialisation code here 
}); 

O la forma abreviada:

jQuery(function() { … }); 

con Prototipo se usaría el dom:loaded event:

document.observe("dom:loaded", function() { 
    // Your initialisation code here 
}); 
+1

DOMContentLoaded en casi todos los navegadores, pero IE <9 – gengkev

+0

No sabía que ahora tenía tanto soporte, supongo que estoy tan acostumbrado a que jQuery me ayude. Gracias @gengkev – georgebrock

0

En lo personal, no tengo problemas al agregar onlclick="doSomething();" al elemento s. Sin lógica, solo una llamada de función.

Toda la lógica está donde debería estar: en la función definida en el HEAD o en un archivo separado.

Dígame cuál es la diferencia cuando agrega href="somepage.html" o incluso href="somepage.html#someanchor" a una etiqueta A.

+0

Rara vez encuentro que tengo solo un enlace que necesita cierto comportamiento; a menudo es un grupo completo de enlaces similares. Cuando ese comportamiento cambia o ya no es necesario, me resulta mucho más conveniente cambiar o eliminar un único archivo '.js' que define el comportamiento y lo vincula a los enlaces relevantes, en lugar de cambiar o eliminar muchos atributos' onclick' en muchos enlaces – georgebrock

+0

@georgebrock Usted podría decir lo mismo si quisiera renombrar/re-estructurar sus archivos HTML - aún tendría que ir a cada etiqueta 'A' y cambiar el atributo' href'. De todos modos, en su caso, no es necesario cambiar el nombre de la función, simplemente volver a escribir la función. Si el comportamiento del onclick está cambiando, quizás valga la pena cambiar el nombre de la función por otra cosa. Usted hace un buen punto sin embargo. – Matthew

+0

Una vez que un sitio web está en la web pública, cambiar los atributos 'href' va a ser un dolor de cabeza de todos modos, porque [los URI geniales no cambian] (http://www.w3.org/Provider/Style/URI) (y cuando tienen que cambiar, deben 301 a las nuevas ubicaciones). Pero yo divago. Ya que puede escribir su JavaScript para que haya un único punto de cambio y una clara separación de las preocupaciones, ¿por qué no hacerlo? – georgebrock

Cuestiones relacionadas