Añadiendo los gestores de eventos

Hubo errores de script en esta página. Mientras los editores del sitio lo solucionan, puedes ver un contenido parcial debajo.

 

{{ Traducción("inglés", "XUL Tutorial:Adding Event Handlers", "en") }}

The find files dialog so far looks quite good. We haven't cleaned it up much but we have created a simple user interface easily. Next, we will show how to add scripts to it.

Usando scripts

Para hacer funcional el diálogo de búsqueda de archivos, necesitaremos algunos scripts los cuales se ejecutarán cuando el usuario interactúe con el diálogo. Podríamos querer agregar un script para manejar el botón Buscar, el botón Cancelar y manejar cada comando del menú. Escribimos esto utilizando funciones JavaScript muchas de la misma forma que en HTML.

Puede utilizar el elemento script para incluir scripts en archivos XUL. Puede incluir el código script directamente en el archivo XUL entre la apertura y cierre de etiquetas script pero es mucho mejor incluir código en un archivo separado ya que de esta manera la ventana XUL cargará ligeramente más rápido. El atributo src es utilizado para enlazar un archivo script externo.

Nuestro ejemplo

Agreguemos un script al diálogo buscar archivo. Aunque no importe cómo sea llamado el archivo script, generalmente debería ser el mismo que el archivo XUL con una extensión .js. En este caso, findfile.js será utilizado. Agregue la línea debajo sólo después de la apertura de la etiqueta window y antes de cualquier otro elemento.

<script src="findfile.js"/>
Nota: Al agregar el elemento script directamente bajo el elemento window su ámbito será el documento completo. Si se anida bajo otra etiqueta su ámbito se restringirá a los elementos anidados en ella, y no sera "visible" para otras zonas de documento.

Crearemos el archivo script más tarde cuando conozcamos qué queremos poner en él. Definiremos algunas funciones en el archivo y podremos llamarlas desde un manejador de eventos.

Puede incluir scripts múltiples en un archivo XUL utilizando múltiples etiquetas script, cada una apuntando a un script diferente. Puede utilizar URLs relativas o absolutas. Por ejemplo, puede utilizar URLs de la siguiente forma:

<script src="findfile.js"/>
<script src="chrome://findfiles/content/help.js"/>
<script src="http://www.example.com/js/items.js"/>

Este tutorial no intenta describir cómo utilizar JavaScript ya que esto es un tópico extenso y hay variedades de otras fuentes que están disponibles para esto.

Por defecto la consola JavaScript sólo muestra errores desde contenido de red. Para mostrar errores en JavaScript chrome, es necesario cambiar la preferencia javascript.options.showInConsole a verdadero. Puede también cambiar la preferencia javascript.options.strict para la depuración. Estableciendo este valor a verdadero, la sintaxis propensa, pobremente escrita y no estándar causa errores lógicos que son guardados en la consola JavaScript.

Respuesta a eventos

El script contendrá código que responderá a varios eventos disparados por el usuario u otras situaciones. Hay más de treinta eventos diferentes que pueden ser manejados de formas distintas. Un evento típico es que el usuario presione un botón del ratón o presione una tecla. Cada elemento XUL tiene la habilidad de disparar varios eventos en diferentes situaciones. Algunos eventos son disparados solamente por determinados elementos.

Cada evento tiene un nombre, por ejemplo, 'mousemove' es el nombre del evento que es disparado cuando el usuario mueve el ratón sobre un elemento de la Interfaz de Usuario. XUL utiliza el mismo mecanismo de evento definido en eventos DOM. Cuando una acción ocurre que debería disparar un evento, tal como que el usuario mueva el ratón, se crea un objeto evento correspondiente a tal tipo de evento. Las propiedades de dicho objeto se establecen de modo que ofrezca información asociada a la circunstancia en que se produjo, tal como: la posición del ratón, la(s) tecla(s) que fue(ron) presionada(s), el botón del ratón que se utilizó, etc.

El evento es enviado luego en fases al XUL.

  • En la fase de captura, el evento primero es enviado a la ventana, luego al documento, seguido por cada ancestro del elemento XUL donde el evento ocurrió hacia abajo hasta que alcance el elemento.
  • En la fase objetivo, el evento es enviado hacia el elemento objetivo XUL.
  • En la fase burbujeante, el evento es enviado a cada elemento de más atrás hasta que alcance nuevamente la ventana.

Puede responder a un evento durante la captura completa de la fase burbujeante. Una vez que el evento ha finalizado de propagarse, cualquier acción por defecto ocurrirá, la cual está incluida en comportamiento del elemento.

Por ejemplo, cuando el ratón sea movido sobre un botón que está dentro de un cuadro, un evento 'mousemove' es generado, y enviado primero a la ventana, seguido por el documento, y luego al cuadro. Eso completa la fase de captura. Luego, el evento 'mousemove' es enviado al botón. Finalmente, la fase burbujeante es esencialmente lo inverso a la fase de captura. Note que algunos eventos no hacen la fase burbujeante.

Puede adjuntar oyentes a cada elemento a ser oído por los eventos durante cada paso de la propagación de eventos. Debido a la forma en que un evento simple es pasado a todos los ancestros, puede adjuntar un oyente a un elemento específico o a un elemento más grande en la jerarquía. Naturalmente, un evento adjunto a un elemento más grande recibirá la notificación de todos los elementos dentro de él, mientras que un evento adjunto a un botón sólo recibirá eventos preparados para ese botón. Esto es útil si hay varios elementos que querrían manejarse utilizando el mismo código o similar.

El evento más común utilizado es el evento 'command'. El evento command es disparado cuando un usuario activa un elemento, por ejemplo presionando un botón, cambiando una casilla de verificación o seleccionando un ítem desde un menú. El evento command es un evento útil ya que automática maneja distintas formas de activar el elemento. Por ejemplo, el evento command ocurrirá sin importar si el usuario utiliza el ratón para seleccionar un botón o presionar la tecla Enter.

Hay dos formas de adjuntar un evento oyente a un elemento. Primero, utilizando un atributo con script como su valor. Segundo, llamando a un método del evento addEventListener. El primero sólo puede manejar eventos burbujeantes pero tiende a ser más simple de escribir. El último puede manejar eventos en cualquier fase y puede también ser utilizado para adjuntar múltiples oyentes para un evento en un elemento. Utilizando la forma atributo es más común para la mayoría de eventos.

Atributos controladores de eventos

Para controlar eventos bajo la forma de atributos se debe asignar un atributo asociado con el evento a controlar en el elemento en en que se desea atraparlo: el atributo será el nombre del evento precedido del prefijo 'on' y se le asignará como valor un llamado a la función o script que se desea ejecutar cuando ocurra el evento. Por ejemplo, para el evento 'command' el atributo correspondiente será 'oncommand' y para 'mouseover' será 'onmouseover'. El código de llamado a la función suele ser muy corto y generalmente llama a un procedimiento que ha sido definido en una etiqueta script o en un archivo separado. A continuación se ofrece un ejemplo de tratamiento de evento en respuesta a pulsar un botón:

Ejemplo 1: {{ Xultu-sv("ex_events_1.xul") }}

<button label="OK" oncommand="alert('Se apretó el botón!');"/>

Como el evento command permea las capas contenedoras (es burbujeante), también es posible ubicar el controlador de eventos en un elemento contenedor. En el ejemplo siguiente, el atributo controlador se establece en una caja y ésta atrapa eventos de los dos elementos que contiene.

Ejemplo 2 : {{ Xultu-sv("ex_events_2.xul") }}

<vbox oncommand="alert(event.target.tagName);">
  <button label="OK"/>
  <checkbox label="Muestra las imágenes"/>
</vbox>

En este ejemplo, el evento command se filtrará desde el elemento en que ocurra - button o checkbox - hasta el elemento vbox, donde es controlado. Si se hubiese colocado un segundo controlador de eventos (atributo oncommand) en el elemento button, su código sería invocado antes, seguido del manejador situado en el elemento vbox. Los controladores de eventos reciben, como argumento implícito, un objeto event al que se puede hacer referencia en código mediante la variable 'event'. Dicho objeto porta, en sus propiedades, la información que específicamente concierne al evento. Cuando varios elementos comparten un controlador de eventos (como en este ejemplo) es usual utilizar la propiedad 'target' del objeto event (event.target), que alberga una referencia al elemento en el que ocurrió. En el código de ejemplo se hace un llamado a la ventana de mensajes para que muestre el nombre de la etiqueta 'tagName' del elemento en que ocurra. La propiedad target resulta útil para controlar la permeabilidad de eventos burbujeantes, de modo que un conjunto de elementos, buttons por ejemplo, comparta y sea controlado mediante un único script.

Nota de traducción: Si se anida controladores de eventos, para un mismo evento, en varias capas; se debe tener cuidado de cancelarlo, una vez controlado en una capa, para evitar que se dispare nuevamente en los controladores situados en las capas contenedoras. A no ser que se desee realizar acciones en cascada.

Se debe notar que la sintaxis para establecer los atibitos controladores es similar a la empleada para asignar eventos en documentos HTML. De hecho, HTML y XUL comparten el mismo mecanismo de definición de eventos. No obstante, hay una diferencia importante: mientras que en HTML se usa el evento 'click' (o el atributo onclick) para responder a acciones sobre los buttons, en XUL se debe usar el evento command en su lugar. XUL soporta el evento click, pero este sólo responde a acciones del ratón (mouse), no al uso del teclado. En consecuencia, se debe evitar el uso del evento click en XUL, a no ser que se tenga alguna razón para responder de modo exclusivo a acciones provocadas con el mouse (ratón). Adicionalmente, cuando se deshabilita un elemento, este no disparará eventos command; mientras que el evento click se produce con independencia de que el elemento en que se dispare esté o no habilitado.

Nuestro ejemplo

Un gestor command se puede agregar a los botones Buscar y Cancelar del diálogo de búsqueda de archivos. Presionar el botón Buscar debe iniciar la búsqueda. Como aún no vamos a implementar el proceso de búsqueda, dejaremos esta parte fuera por un rato. Presionar el botón Cancelar debe cerrar la ventana. El código de abajo muestra como hacer esto. Mientras estamos aquí, añadimos el mismo código al menuitem Cerrar.

<menuitem label="Cerrar" accesskey="c" oncommand="window.close();"/>
...
  
<button id="cancel-button" label="Cancelar"
     oncommand="window.close();"/>

Aquí se añadieron dos gestores. El atributo oncommand fue añadido al menuitem Cerrar. Usando este gestor, el usuario podrá cerrar la ventana dando click al menuitem con el mouse o seleccionándolo con el teclado.El gestor oncommand también fue añadido al botón Cancelar.

Controladores de eventos asignados mediante métodos del DOM

Una segunda vía para asignar controladores de eventos a los elementos es usar su método addEventListener. Este camino permite agregarlos dinámicamente y escucharlos durante la fase de captura. A continuación se ilustra la sintaxis:

Ejemplo 3: {{ Xultu-sv("ex_events_3.xul") }}

<button id="okbutton" label="OK"/>

<script>
function buttonPressed(event){
  alert('Se apretó el botón!');
}

var button = document.getElementById("okbutton");
button.addEventListener('command', buttonPressed, true);
</script>

La función getElementById() devuelve el elemento cuyo Id sea pasado como parámetro; en este caso, el button "okbutton". Luego se llama a la función addEventListener() de dicho elemento para agregarle un controlador de eventos: su primer argumento es el nombre del evento al que se va a responder, el segundo es el mombre de la función a llamar cuando el evento ocurra y finalmente, el último argumento debe ser true para controladores en la fase de captura. Si se desea permitir que el evento pase a otras fases se debe asignar el último argumenta como false. La función pasada como segundo argumento, debe a su vez, tener un argumento para pasar el objeto event, como se muestra en la declaración de la función buttonPressed arriba.

Nuestro ejemplo hasta aquí: {{ Xultu-sv("/findfile/findfile-events.xul") }}

Seguimos con más detalles sobre los eventos.

{{ AnteriorSiguiente("Tutorial de XUL:Menúes con desplazamiento", "Tutorial de XUL:Más gestores de eventos") }}

{{ languages( { "en": "en/XUL_Tutorial/Adding_Event_Handlers", "fr": "fr/Tutoriel_XUL/Ajout_de_gestionnaires_d\'\u00e9v\u00e8nements", "ja": "ja/XUL_Tutorial/Adding_Event_Handlers", "pl": "pl/Kurs_XUL/Dodawanie_funkcji_obs\u0142ugi_zdarze\u0144" } ) }}

Etiquetas y colaboradores del documento

Colaboradores de esta página: ibnkhaldun, Markens, Nathymig, Camposuma, Mgjbot, Maharba
Última actualización por: ibnkhaldun,