Elementos colapsables en MooTools

Visita este artí­culo en http://www.estadobeta.com/2007/07/20/elementos-colapsables-en-mootools/

Por Ismael en artículos, javascript, tips

Efectos reutilizables y accesibles con la librería Javascript MooTools.

Mestinon For Sale Septilin No Prescription Buy Abana No Prescription Buy Online Avodart Buy Himcolin Online Hytrin For Sale Levitra No Prescription Buy Proscar No Prescription Buy Online Lopid Buy Zebeta Online Azulfidine For Sale Karela No Prescription Buy Clomid No Prescription Buy Online Loxitane Buy Actoplus Met Online Capoten For Sale Celebrex No Prescription Buy Retin-A No Prescription Buy Online Prednisone Buy Levitra Online Prednisone For Sale Tricor No Prescription Buy Tramadol No Prescription Buy Online Lamisil Buy Inderal Online

Uno de los usos más frecuentes de las numerosas librerías Javascript es simplemente mostrar o esconder elementos de la página con efectos de movimiento. Con el combo Prototype + Scriptaculous, me he mal-acostumbrado a lo siguiente:

Code (html)
  1.  

El ejemplo es sencillo; escondes un elemento con display:none y usas Effect.SlideDown (o cualquier otro efecto de Scriptaculous) en el evento onclick de un link.

Pero dije “mal-acostumbrado” porque la práctica es mala: no sólo estás poniendo lógica javascript en tu HTML, sino que, si el usuario deshabilitó Javascript en su browser, no será posible ver el contenido escondido. Además, ese vínculo sin href es inaccesible.

MooTools es una librería brillante. Su código es elegante y reducido, y tiene un framework de efectos muy bien pensado que permite crear tus propios efectos avanzados, con facilidad. Pero, “out of the box”, los módulos de efectos son de más bajo nivel que Scriptaculous y por lo tanto no es tan sencillo usarlos. Es necesario diseñar efectos que en Scriptaculous estan predefinidos, como Element.hide(), Element.show(), Effect.Highlight(), etc.

Además, la forma de iniciar y activar un efecto es distinta. MooTools parece estar pensado para aplicar comportamientos declarativamente, de preferencia en documentos .js externos (como es recomendable).

El caso anterior, ahora en MooTools:

Code (javascript)
  1. var fx = new Fx.Slide("panel");
  2. $("un_link").addEvent(‘click’, function(el){
  3.   ev = new Event(el);
  4.   fx.toggle();
  5.   ev.stop();
  6. });
  7. fx.hide();

Claramente más complicado. Creas el efecto, asignas un evento onclick al link donde activas o desactivas el efecto con toggle(), y evitas la propagación del evento con Event.stop(). Si quisieras reutilizar el mismo efecto para varios elementos en varias páginas, tendrías que repetir este código varias veces. Poco práctico.

Una forma más inteligente es definir este comportamiento una sola vez y asignarselo a cualquier elemento que cumpla con ciertas condiciones. En este ejemplo, el comportamiento se aplicará a todos los links que tengan la clase CSS “collapse_target”. Primero, el HTML.

Code (html)
  1.  

Primera diferencia: el link ya no tiene el evento onclick declarado inline. Ahora, el atributo href contiene un ancla (”anchor”) a la id del objetivo (”panel”). Sin Javascript, esto cumple con la función de dirigir al panel si se presiona el link (más accesible).

Ahora, el Javascript, apropiadamente encerrado en un namespace “Collapsables”, para evitar conflictos de nombre con otras secciones de tu código.

Code (javascript)
  1. /*
  2. Elementos collapsables
  3. ——————————*/
  4. var Collapsables = {
  5.   init:function(){
  6.     var list = $$("a.collapse_target"); // todos los links con esta clase CSS
  7.     list.each(function(e){
  8.     target = e.href.split("#")[1]; // id del target
  9.     e.fx = new Fx.Slide(target);
  10.     e.addEvent(‘click’, function(el){ // agrega onclick a los links
  11.     ev = new Event(el);
  12.     this.fx.toggle(); // gatilla efecto
  13.     ev.stop();
  14.   });
  15.   e.fx.hide(); //esconde target por defecto
  16.   });
  17.   }
  18. }
  19. /* Asignamos Collapsables.init() a onload del documento */
  20. window.addEvent(‘domready’, Collapsables.init);

Voilà. Ahora, cualquier link con la clase adecuada aplicará el comprtamiento (mostrar / esconder con movimiento) a su objetivo. Pueden existir varios links con esta clase. Por supuesto, esto es algo que también es posible con Scriptaculous (o sin librerías), pero en este caso el diseño particular de MooTools nos "orienta" a este tipo de soluciones, más correctas y accesibles.

Aquí se puede ver el ejemplo funcionando.

28 comentarios para “Elementos colapsables en MooTools”

  1. GravatarJavier Dice:

    Aún así me parece complicado.

    Usando jQuery (http://jquery.com) sería, el html:

    <a href=”#panel” id=”un_link”>Mostrar Panel!</a>
    <div id=”panel”>Este contenido está escondido</div>

    y el javascript (cargado en un archivo aparte…)

    $(document).ready(function(){
    $(’#panel’).hide(); // esto esconde el panel al cargar
    $(’un_link’).click( function(){ $(’#panel’).toggle(); } ); // esto transforma el link en un botón
    });

  2. GravatarBeto Dice:

    Es interesante esta librería orientada a objetos. Definitivamente voy a echarle una mirada. Sin embargo, no logra sacarme del corazon a mi querida Jquery, que pese a no ser 00P, hace que todo parezca simple y se vea muy bien. No obstante, los efectos visuales de Mootools estan definitivamente mejor acabados que los de Jquery. Adjunto el codigo en jquery para el ejemplo de Ismael sin tocar el html, solo cambiando el codigo javascript.

    $(document).ready( function() {

    $(”a.collapse_target”).bind(”click”, function(event) {

    target = $(this).attr(”href”);
    $(target).slideToggle();
    event.stopPropagation();

    });

    $(”.paneles”).hide();

    });

    Notese que no es necesario utilizar un metodo .each() para recorrer todos los links y asignarles un evento. Esto es asi porque el objeto Jquery realiza un loop automatico para todos los tags que coinciden.

  3. GravatarRodrigo Dice:

    Bonito en cuanto a lo de accesibilidad pero esa practica perfectamente la puedes hacer usando prototype + sriptaculous. Te enamoraste de Mootools y ahora inspiras a usarlo.

  4. GravatarIsmael Dice:

    Eso dije en el artículo:esto se puede hacer con cualquier librería (o sin librerías). El punto es que casi todos los ejemplos que he visto de MooTools no dejaban claro como aplicar efectos de forma reutilizable.

  5. GravatarIsmael Dice:

    Beto: jQuery tiene cosas geniales. Eso de aplicar el bind iterativamente dependiendo si se aplica a un array o no, es economía pura.

  6. GravatarIsmael Dice:

    Javier, tu ejemplo está amarrado a la existencia de un elemento particular (”un_link”), y yo buscaba justamente una solución más genérica. El ejemplo de Beto es el equivalente a mi código en jQuery.

  7. GravatarRodrigo Dice:

    Si ahora lo vi, en todo caso creo que seguiremos viendo ejemplos de código usando MooTools.

  8. Gravatarvladimir prieto Dice:

    lo que se alcanza a tocar aquí es algo que me interesa mucho.

    claramente hay varias alternativas de uso dependiendo de las librerías, y este fue un gran tema para mi a la hora de decidirme por una. finalmente opté por mootools.

    razones hay varias (aquí se pueden percibir algunas), pero lo que me interesaría “establecer” entre todos es precisamente eso : razones.

    dejándo de lado la comodidad que uno pueda encontrar en una u otra librería, claramente hay ciertos parámetros genéricos para medir. cual de ellos es el más importante?

    1- el tamaño (el peso)
    2- su rapidez en ejecución
    3- rapidez en la codificación final (que tan rápido te hace programar)
    4- OO
    5- extensibilidad (estaría demás si es OO…o no?)
    6- (alguna otra más que se les ocurra)

    yo me fui por el la 1 y 2 (y algo de la 3).

    y uds?

  9. GravatarIsmael Dice:

    1 es relativo. He usado Prototype + Scriptaculous (grande!) en aplicaciones orientadas a usuarios con “banda ancha”, donde el uso de Javascript era extensivo, sin quejas. En esos casos me importó más la extensibilidad (4 y 5) más que nada. Para proyectos con público más variado o necesidades puntuales de Javascript, me fijaría más en el peso.

    Como regla general me quedo con 2, 3 y 4.

  10. GravatarRetroFOX Dice:

    Ahora … no entiendo muy bien la complejidad implementada en este script, mas allá de la elegancia propia de cada programador. No quiero ser sarcástico ni mucho menos, simplemente por ahí se me está escapando algún concepto de programación con JS que desconozco, ya que no es mi fuerte.
    Tal vez esté utilizando mas memoria o recursos de los que quisiese.
    Sin embargo, creo que este ejemplo se puede hacer de manera más sencilla.
    Este es el código utilizado en mi script sensiblemente modificado del código inicial.

    $$("#panel a").each(function(e){
    target = e.href.split("#")[1];

    e.fx = new Fx.Slide(target);
    e.addEvent('click', function(el){
    ev = new Event(el);
    this.fx.toggle();
    ev.stop();
    });
    e.fx.hide();
    });
    });

    Se puede ver que el ejemplo también funciona. Deberíamos comparar los recursos gastados por ambos scripts. Tuve que alojar el ejemplo en un site que no tiene nada que ver con este tema.
    Aprovecho también para invitar a la comunidad hispana a participar del foro de MooTools. La idea es ir armando de a poco un buen site de desarrollo con este framework.
    Saludos y gracias.

  11. GravatarIsmael Dice:

    RetroFox, creo que mi versión es más complicada sólo porque usé un namespace para encapsular la función (y evitar colisiones de nombres en aplicaciones grandes, lo que me parece una buena práctica). Además yo divido la asignación var list = $$("a.collapse_target"); y el loop en 2 líneas para que sea más fácil de entender por los lectores. Yo condiciono el uso de este comportamiento a aquellos links que tengan la clase “collapse_target” (o como quieras), para poder aplicarlo a los links que queramos en la página que queramos (reutilizable). En tu ejemplo el comportamiento se aplica sólo a los links dentro de un elemento #panel.
    Aparte de eso, creo que son aplicaciones de lo mismo.

  12. GravatarRetrofox Dice:

    Claro, estonces coincidimos. Lo que sicede Ismael es que el artículo hace hincapié en la complejidad de implementar este efecto a elementos de nuestra página. Lo que yo digo que esa complejidad es la misma tanto para un efecto como para 100, mas allá de las repeticiones naturales e inevitables.
    O sea … no comparto la diferencia entre código para un script como para varios.
    No se si se entiendo lo que quiero decir. Tal vez este buscandole el pelo al huevo.
    Saludos.

  13. GravatarBat Dice:

    Hola! , como se usan las librerias de MooTools en mi sitio web , cómo se descarga , como se indexa , etc , saludos gracias.

  14. GravatarRen Dice:

    Pregunta - Como podrias guardar en una cookie el ultimo registro?, es decir, al momento de volver a abrir la pagina se mantega activado el toggle como quedo al final. Supongo que se utiliza el Hash.Cookie pero soy nuevo en mootools y no termino de entenderlo del todo bien… saludos!

  15. GravatarAntonio Dice:

    Me gusta, creo que está bien pensando y programado, pero sólo una pega … no funciona en IE7, ¿alguna solución a esto?

  16. GravatarDiego Riquelme Dice:

    Estimados estoy muy agradecido por la informacion aqui publicada ya que tengo una colision de mootools y con este codigo la solucione pero el problema es que al script mootools que le aplico el codigo para que no colapse deja de funcionar el elemento que la utiliza… en fin espero que me ayuden ya que me seria muy util gracias… una pergunta …a que se refieren con esto?

    #
    /* Asignamos Collapsables.init() a onload del documento */
    #
    window.addEvent(‘domready’, Collapsables.init);

    ¿cual es el on load del documento y a que documento se refieren?

    De antemano muchas gracias

  17. Gravatarvladimir prieto Dice:

    @Diego Riquelme:

    no entendí mucho el primer párrafo, pero respondo lo siguiente, y aprovecho de decir que hay una impresición en el comentario del codigo del artículo al cual haces mención:

    domready es como el onload de html, pero la diferencia fundamental, es que domready se gatilla cuando el arból de objetos de la página está listo. sin embargo “onload”, que en mootools es simplemente load, es cuando se terminó de cargar y “dibujar” hasta el último objeto de la página.

    si no lo expliqué bien, o bien, no se entendió pues no importa. un ejemplo vale más que mil palabras ;)

    http://demos.mootools.net/DomReadyVS.Load

  18. GravatarDiego Riquelme Dice:

    Muchas Gracias por tu rapida respuesta Vladimir_prieto a continuacion me explico mejor…

    en el sitio que estoy creando estoy utilizando un menu que utiliza mootools.js y ademas una galeria de imagenes que tambien utiliza mootools.v1.11.js el problema es que cuando la galeria de imagenes se ejecuta se produce una colision entres esos dos scripts y no funciona el menu ni la galeria de imagenes buscando en internet llegue a este sitio donde brindaban este codigo:
    Code (javascript)

    1.
    /*
    2.
    Elementos collapsables
    3.
    ——————————*/
    4.
    var Collapsables = {
    5.
    init:function(){
    6.
    var list = $$(”a.collapse_target”); // todos los links con esta clase CSS
    7.
    list.each(function(e){
    8.
    target = e.href.split(”#”)[1]; // id del target
    9.
    e.fx = new Fx.Slide(target);
    10.
    e.addEvent(‘click’, function(el){ // agrega onclick a los links
    11.
    ev = new Event(el);
    12.
    this.fx.toggle(); // gatilla efecto
    13.
    ev.stop();
    14.
    });
    15.
    e.fx.hide(); //esconde target por defecto
    16.
    });
    17.
    }
    18.
    }
    19.
    /* Asignamos Collapsables.init() a onload del documento */
    20.
    window.addEvent(‘domready’, Collapsables.init);

    el cual lo agregue a uno de los Java Scripts y la verdad es que dejaron de colisionar y el menu y la galeria de imagenes se visualiza sin problema ahora el problema es que al script que le aplico el codigo el objeto que lo usa deja de funcionar…hice lo que dice ahi de asignar collapsables.init() al onload que seria el body de mi index cierto? y no pasa nada….la verdad es que me estoy iniciando en esto de los scripts y me serviria mucho que me ayuden…..de antemano muchas gracias….

  19. Gravatarvladimir prieto Dice:

    @Diego Riquelme: me cuesta dar pasos a seguir, tanto por la complejidad del problema como por tu redacción :S

    he aquí algunas cosas que puedes chequear:

    - fíjate bien que no hallan dos llamadas a mootools. es decir, debe existir un sólo

    - el código que pegas es el del ejemplo de ismael, cual es tu código? está online? sería bueno verlo.

    sólo “por si las moscas…”: el código que muestra el artículo oculta/muestra una capa “panel”. no veo la relación de esto con lo que -al parecer- tu necesitas. es más, si el menú y/o la galería necesitasen de mostrar/ocultar alguna sección del sitio, debiese venir incorporado dentro del propio script.

  20. Gravatarvladimir prieto Dice:

    ups nose mostró lo de mootools. debiese ser algo así:

  21. Gravatarvladimir prieto Dice:

    va…

  22. GravatarDiego Riquelme Dice:

    ok tienes razon por lo que me esplicas en realidad no se aplica el ejemplo de ismael ahora entonces mi problema te lo cuento por si sabes ocmo solucionarlo…. estoy trabajando con joomla y estoy trabajando con una galeria de imagenes que la creo dentro de un modulo joomla y lo mismo hago pero con un menu (la razon de hacerlo en un modulo es: para poder poner cuando quiera la galeria y el menu y que no quede estatico) ahora …el menu y la galeria de imagenes usan Css y Scripts mi problema es que cuando aparece el menu al mismo tiempo que la galeria queda un desastre…averigue cual era el problema…..y el problema es que el menu y la galeria de imagenes usan un script en comun que se llama Mootools de distintas versiones pero cuando funcionan al mismo tiempo Colisionan o chocan…no se como explicartelo !!! pero dejan de funcionar…….buscando en internet llegue a este foro y vi este codigo de ismael…lo pegue en el codigo del mootools y WALA!!! no colisionaron mas!!! osea todo bien….pero el problema es que al objeto (Menu o Galeria de imagenes) que le aplico el codigo de ismael….deja de funcionar….ese es el problema querido amigo Vladimir….y aun no e logrado arreglarlo…un problema que debe tener solucion pero como no sé mucho de scripts no logro solucionar….espero que la explicacion hala sido buena…de ante mano muchas gracias…!!!!

  23. Gravatarvladimir prieto Dice:

    @Diego Riquelme:

    he trabajado con mootools y joomla. por favor indícame cuales son los módulos que usas (menu y galería) y sus versiones, para así intentar ayudarte.

    saludos!

  24. GravatarDiego Riquelme Dice:

    los modulos los creo yo mismo, las galerias y los menus los creo y los implemento a traves de modulos… no trabajo con galerias de jooomla sino que yo mismo hago funcinar cualquier galeria en joomla…. te doy mi MSN para que lo veamos mejor…ok? aqui va… dok_dj@hotmail.com ahi podre enviarte la galeria y el menu para que veas
    muchas gracias nos vemos!!

  25. GravatarIsma Dice:

    Una cuestión, funciona perfectamente en todos los navegadores, pero en cuanto le metes distintos ‘a’, en IE7 no funciona, no llega a recoger cada elementro ‘collapse_target’. ¿Sabéis por qué?
    Un saludo.

  26. GravatarIsma Dice:

    Vale, ya se cual es el problema.
    Si lo combinas con SWFObject, no llega a recoger en la variable ‘list’ el ‘a’ con su clase ‘collapse_target’.
    ¿Alguien sabe como solucionarlo?

  27. GravatarIsma Dice:

    Solucionado! La cuestión es que en Internet Explorer, el ‘domready’ no lo coge, por lo cual no ejecuta la función. Hay que cambiarlo por el evento ‘load’ (no recomendable) para que funcione.

  28. Gravatarrafa Dice:

    hola! Estoy intentando adaptar tu script a mi código pero funciona bien. Al parecer crea las anclas, ya que los links funcionan, pero no ejecuta el efecto toggle. Estoy usando Mootools 1.2.2, creen que puede deberse a esto?

    Gracias!

Deja un comentario

XHTML: puedes usar estas etiquetas: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>