2012-05-15 14 views
100

Sé que esta es una mala práctica. No escriba código como este si es posible.¿Cómo funciona Javascript en línea (en HTML)?

Por supuesto, siempre nos encontraremos en situaciones donde un fragmento inteligente de Javascript en línea puede resolver un problema rápidamente.

estoy persiguiendo esta consulta en aras de la plena comprensión de lo que sucede (y los peligros potenciales) cuando algo como esto está escrito:

<a href="#" onclick="alert('Hi')">Click Me</a> 

Por lo que yo puedo decir que esto es funcionalmente el mismo que

<script type="text/javascript"> 
    $(function(){ // I use jQuery in this example 
     document.getElementById('click_me').onclick = 
      function() { alert('Hi'); }; 
    }); 
</script> 
<a href="#" id="click_me">Click Me</a> 

Extrapolando esta parece que la cadena asignada a atribuir onclick se inserta dentro de una función anónima que se asigna al controlador click del elemento. ¿Es este realmente el caso?

porque estoy empezando a hacer cosas como esta:

<a href="#" onclick="$(this).next().fadeIn(); return false;">Display my next sibling</a> <!-- Return false in handler so as not to scroll to top of page! --> 

que trabaja. Pero no sé cuán pirata es esta. ¡Parece sospechoso porque no hay una función aparente de la que se está devolviendo!

Puedes preguntar, ¿por qué estás haciendo esto, Steve? Inline JS es una mala práctica!

Bueno, para ser sincero, estoy cansado de editar tres secciones diferentes de código solo para modificar una sección de una página, especialmente cuando estoy creando prototipos de algo para ver si funciona. Es mucho más fácil y, a veces, incluso tiene sentido que el código específicamente relacionado con este elemento HTML se defina en el elemento: cuando decido 2 minutos después que esta fue una idea terrible y terrible, puedo destruir el div completo (o lo que sea) y no tengo un montón de misteriosos JS y CSS cruft en el resto de la página, lo que ralentiza el renderizado muy ligeramente. Esto es similar al concepto de localidad de referencia, pero en lugar de fallas en el caché, estamos viendo errores y bloat de código.

+3

Estás en lo correcto, es una función anónima. – bhamlin

+1

Deberá enganchar la consulta para '# click_me' en el evento DOMready, o colocar la secuencia de comandos después del nodo. – Bergi

+1

En una consola, haga 'document.getElementById (" click_me "). Onclick;'. O alerta. Verás que está en una función. –

Respuesta

76

Lo tiene casi correcto, pero no ha contabilizado el valor this suministrado al código en línea.

<a href="#" onclick="alert(this)">Click Me</a> 

es en realidad más cerca de:

<a href="#" id="click_me">Click Me</a> 
<script type="text/javascript"> 
document.getElementById('click_me').addEventListener("click", function(event) { 
    (function(event) { 
     alert(this); 
    }).call(document.getElementById('click_me'), event); 
}); 
</script> 

Inline controladores de eventos establecen this igual al destino del evento.

+7

El script debe venir después de la etiqueta, de lo contrario, la etiqueta no existe cuando se ejecuta: sugiero cambiar su respuesta para reflejar esto. – undefined

3

¡Parece sospechoso porque no hay una función aparente de la que se devuelve!

Es una función anónima que se ha adjuntado al evento click del objeto.

¿por qué haces esto, Steve?

¿Por qué diablos se le doi ..... Ah importa, como se ha mencionado, lo que realmente es adoptado ampliamente mala práctica :)

8

Lo que hace el navegador cuando se tiene

<a onclick="alert('Hi');" ... > 

es fijar el valor real de "onclick" a algo efectivamente como:

new Function("event", "alert('Hi');"); 

es decir, se crea una función que espera un "evento" pa rameter. (Bueno, IE no, es más como una simple función anónima simple.)

+1

Ah. ¡De modo que puedo usar la variable 'event' para recuperar el evento (y el elemento originario de él a través de' event.target'), de mi fragmento JS en línea! Guay. –

+1

IE realmente no pasa el parámetro 'event', pero si usa' event' dentro de esta función anónima, IE lo entenderá como el Objeto de Evento real.Como la función anónima se establece como una propiedad del objeto 'window' en IE, verá esto como' window.event'. – PanterA

+0

@rbyte sí, eso es correcto. – Pointy

4

La mejor manera de responder a su pregunta es see en acción.

<a id="test" onclick="alert('test')"> test </a> ​ 

En el js

var test = document.getElementById('test'); 
console.log(test.onclick); 

Como se ve en la console, si estás usando Chrome se imprime una función anónima con el objeto de evento pasado en, aunque es un poco diferente en IE.

function onclick(event) { 
    alert('test') 
} 

Estoy de acuerdo con algunos de sus puntos acerca de los controladores de eventos en línea. Sí, son fáciles de escribir, pero no estoy de acuerdo con su idea de tener que cambiar el código en varios lugares, si estructura bien el código, no debería necesitar hacer esto.

+0

Creo que algo como '' está perfectamente bien para la creación de prototipos. Desea probar algo que requiere la interacción del usuario en este momento, y de todos modos lo eliminará más tarde. ¿Por qué escribir código adicional en todo el lugar? –

+0

No es un código adicional, solo una función anónima adicional. Y no está por todos lados, en realidad está todo en un solo lugar, en las etiquetas de script. –

+0

No estoy seguro de que compartamos la misma idea de "estructurar bien su código". Si vincula la interfaz de usuario a sus "funciones centrales" en el lugar donde realmente viven sus funciones centrales, esto me parece una disposición de acoplamiento peor que solo vincularlas en la interfaz de usuario. Por lo general, mantengo todas las cosas vinculantes de UI separadas de las cosas centrales, y tengo la sensación de que OP también podría ... –

3

Prueba esto en la consola:

var div = document.createElement('div'); 

div.setAttribute('onclick', 'alert(event)'); 

div.onclick 

En Chrome, que muestra esto:

function onclick(event) { 
    alert(event) 
} 

... y el name propiedad no estándar de div.onclick es "onclick".

Por lo tanto, si esto es anónimo o no depende de su definición de "anónimo". Comparar con algo así como var foo = new Function(), donde foo.name es una cadena vacía, y foo.toString() producirá algo así como

function anonymous() { 

} 
+0

Esto comenzó como un comentario sobre la respuesta de Pointy, pero realmente no funcionó como un comentario. Aquí es realmente la mejor respuesta, creo. –

5

Parece que hay una gran cantidad de mala práctica se lanza alrededor de controlador de eventos atributos. La mala práctica es no conocer y usar las funciones disponibles donde sea más apropiado. Los atributos del evento son completamente documentados por el W3C y no hay nada malo en ellos. No es diferente a colocar estilos en línea, que también está documentado en W3C y puede ser útil en ocasiones. Ya sea que lo ubiques envuelto en etiquetas de scripts o no, se interpretará de la misma manera.

https://www.w3.org/TR/html5/webappapis.html#event-handler-idl-attributes

+1

Sí, estoy dispuesto a aceptar, e incluso proporcioné "razones" razonables de por qué este tipo particular de uso del código en línea podría justificarse en ciertas situaciones. Pero la realidad es que cuando una aplicación (aplicación web o de otro tipo) llega a tener cierta complejidad (y esto ni siquiera suele tomar mucho tiempo o trabajo para alcanzar) tener pequeños fragmentos de * código * esparcidos sobre el diseño HTML * * es probable que sea arquitectónicamente defectuoso desde una perspectiva de mantenimiento. Incluso al comenzar a codificar directamente JS dentro de un archivo HTML, por ejemplo, uno está tentando la pendiente resbaladiza de la espaguetización. –

+1

Y ese es un argumento válido en contra, en el que estoy de acuerdo. Normalmente no agrego secuencias de comandos en línea, ni el estilo de ese tema, yo mismo. Pero las personas tienen diferentes gustos. A muchos, por ejemplo, les gusta agregar etiquetas de guiones y estilos en la sección del cuerpo, no puedo soportarlo. Pero es válido y le gusta a algunas personas. Lo que parece ser una 'mala práctica/espaghettificación' para algunos, es 'buena práctica/estructura' para otros. –

Cuestiones relacionadas