Ticker (NewsTicker) con MooTools
Como implementar un ticker de noticias, o cualquier listado sin importar las etiquetas de listas, con MooTools (habitualmente con efecto scroll).[...]
- 25
- abr
- 2010
Publicado por J.A.Cobo.
Guardado en Desarrollo web, JavaScript.
hace 4 meses y 2 semanas
No hay comentarios
Contexto
Hace poco tiempo que decidí cambiar de framework Javascript, en concreto desde que vi los problemas que jQuery tenía para trabajar con DOM distinto de HTML. Mi elección entonces fue volver a Prototype para más tarde pasarme a MooTools.
Objetivo
Ahora estoy migrando el Javascript que uso en algunos sitios a esta librería, MooTools, y con esta entrada trato de ilustrar lo intuitivo y fácil que resulta trabajar con MooTools para extender Javascript y adaptarlo de una forma estándar a tus propósitos. Es, a diferencia de jQuery, para lo que está hecha esta librería.
Newsticker
Aunque es espectacular el ritmo de crecimiento de los plugins para MooTools en su sección Forge y en concreto los slideshow de varios tipos, lo cierto es que no encontraba un scroll de noticias sencillo -técnicamente más conocidos como ticker o newsticker-.
Haberlos los hay, pero ninguno satisfacía mis necesidades pues: o generaban marcado que no me parecía correcto; o se basaban en procesos demasiado estrictos, demasiado complicados; o se basaban más bien en CSS. …O sea, todo demasiado estricto y yo solo quería implementar la funcionalidad para cualquier listado independientemente del estilo CSS asignado y de su marcado.
Así que, como en otras ocasiones -en las BeTools por ejemplo- e inspirado en la idea de Antonio Lupetti para jQuery (es un ciclo de posiciones básicamente), decidí ponerme manos a la obra y reinventar la rueda porque a veces sigue siendo la mejor solución para conseguir exactamente lo que quieres, como en este caso.
Código NewsTicker con MooTools
Esta es la clase que he implementado, nada del otro mundo pero que me funciona perfecta y hace exactamente lo que quiero:
Funcionalidad
- Me permite aplicarlo a cualquier elemento que contenga hijos, ya sea un listado o no, aunque obviamente lo recomendable y más fiable son los listados.
- Me permite mantener el estilo original de los elementos abstrayéndose de si se usan o no para el ticker. El ticker simplemente aplica el estilo mínimo para la funcionalidad, en este caso la visualización de un solo item del listado y de acuerdo a la altura original del elemento. Es decir, olvídate de anchos o altos estrictos preestablecidos, es la funcionalidad y punto.
- El resto ya es lo normal: tiempo entre repeticiones, establecer un efecto, etc.
Actualizado
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | /** * MooTools NewsTicker by Covi. * * Inspirado en la idea de Antonio Lupetti * (http://woork.blogspot.com/2009/05/how-to-implement-news-ticker-with.html) * * @author Covi * @copyright 2010 J.A.Cobo (Covi) * @version 0.1beta * @todo Interfaz y extender para ticker pequeño, slideshow... * * @license MIT License http://www.opensource.org/licenses/mit-license.php Copyright (c) 2010 J. A. Cobo Ruz (Covi), inspired by Antonio Lupetti cycle idea. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ var NewsTicker = new Class({ Implements: Options, options: { autostart: true, // Comenzar automático o no. animation: 'fade', // Tipo de animación, por el momento: fade, slide (mode:horizontal|vertical). mode: 'vertical', // Para animación slide. transition: 'sine:out', // TODO slide con transición expo da error pues no crea el div vacío. speed: 1000, // Velocidad de la transición en efectos. periodical: 5000, // Periocidad de la iteración sobre los ítems. padding: 0, // Aplicar espaciado a cada ítem si se desea (en un futuro será estilo completo). fixedHeight: true // Alto fijo o flexible para adaptarse al alto de cada ítem. }, /** * Constructor */ initialize: function(el, options) { this.timer = null; this.container = el; this.setOptions(options); if ( null === this.container ) throw new Error('El contenedor de la lista no se encontró.'); // # Setup container: Establecer el alto al primer hijo del container: this.container.setStyles({ 'height': this.container.getFirst().getComputedSize().totalHeight + this.options.padding.toInt(), 'overflow': 'hidden' }); // Eventos y run... if ( true === this.options.autostart ) { this.run(); } }, /** * Efecto. * @access private */ _animate: function() { var item = this.container.getFirst(); // Primer elemento del listado var first = item.clone(); // Clonar el ITEM ORIGINAL para situarlo al final // Eliminar y efecto: switch ( this.options.animation ) { // # FADE: default: case 'fade': item.set('tween', { duration: this.options.speed, transition: this.options.transition, onComplete: function() { this._cycleItem(item, first); }.bind(this) }).tween('opacity', 0); break; // # SLIDE: case 'slide': item.set('slide', { duration: this.options.speed, transition: this.options.transition, mode: this.options.mode, onComplete: function() { this._cycleItem(item, first); }.bind(this) }).slide('out'); break; } }, /** * Ciclo: Eliminar el ítem y pasarlo al final. * @access private */ _cycleItem: function(item, first) { if ( !$chk(item) || !$chk(first) ) return; var itemHeight = item.getComputedSize().totalHeight; // Alto del ítem para ajustar el container // Eliminar y copiarlo al final: item.dispose(); this.container.grab(first, 'bottom'); // FIXME Eliminar el div vacío que deja slide (para MooTools 1.2.6) // @see https://mootools.lighthouseapp.com/projects/24057/tickets/194-fxslide-sometimes-clips-the-contents-of-divs if ( 'slide' === this.options.animation ) { var wrongDivSlide = this.container.getFirst(); if ( 'div' == wrongDivSlide.get('tag') ) { wrongDivSlide.dispose(); var nextItem = this.container.getFirst(); // Para el ajustar el alto del container, volvemos a coger el ítem superior. itemHeight = nextItem.getComputedSize().totalHeight; if ( 'horizontal' == this.options.mode ) { var myFx = new Fx.Slide(nextItem, { duration: this.options.speed, transition: this.options.transition, mode: this.options.mode }); myFx.hide().slideIn(); } } } // Si no se establece como alto fijo, ajustamos el alto del container: if ( false === this.options.fixedHeight ) { this.container.setStyle('height', itemHeight); } }, /** * Inicia el bucle para iterar sobre los ítems. */ start: function() { this.timer = this._animate.periodical(this.options.periodical, this); }, /** * Detiene el bucle. */ stop: function() { $clear(this.timer); }, /** * Lanza todo el proceso: establece, si procede, el bucle y los eventos. */ run: function() { this.container.addEvents({ "mouseover": function() { this.stop(); }.bind(this), "mouseout": function() { this.start(); }.bind(this) }); this.start(); } }); |
Uso
Por ejemplo para elementos con la clase newsticker:
1 2 3 4 5 6 | $$('.newsticker').each(function(item){ var myTicker = new NewsTicker(item, { periodical: 5000, animation: 'slide' }); }); |
Opciones
Las opciones, valga la redundancia, son opcionales ya que se establecen las siguientes por defecto:
1 2 3 4 5 6 7 8 9 10 | options: { autostart: true, // Comenzar automático o no. animation: 'fade', // Tipo de animación, por el momento: fade, slide (mode:horizontal|vertical). mode: 'vertical', // Para animación slide. transition: 'sine:out', // TODO slide con transición expo da error pues no crea el div vacío. speed: 1000, // Velocidad de la transición en efectos. periodical: 5000, // Periocidad de la iteración sobre los ítems. padding: 0, // Aplicar espaciado a cada ítem si se desea (en un futuro será estilo completo). fixedHeight: true // Alto fijo o flexible para adaptarse al alto de cada ítem. } |
- (Boolean) Autostart (true): true|false. Comenzar o no automáticamente, obvio.
- (String) Animation (‘fade’): fade|slide por el momento. Tipo de animación (efecto) a usar en las transiciones de ítems.
- (String) Mode (‘vertical’): vertical|horizontal. Modo del efecto slide si se usa..
- (String) Transition (‘bounce:out’): Fx.Transitions (sine|bounce|bounce:in|…). Tipo de transición para el efecto.
- (Integer) Speed (1000): Número. Velocidad de la transición (opción anterior) del efecto.
- (Integer) Periodical (5000): Número. Lapso de tiempo entre el intercambio de ítems.
- (Integer) Padding (0): Número. Espaciado a aplicar al item.
Me gustaría hacer de esto una opción para aplicar un estilo completo si se decide, daría más control sobre la visualización y corregiría posibles fallos que pudiera haber. - (Boolean) FixedHeight (true): Número. Alto fijo o flexible para adaptarse al alto de cada ítem.
Notas
Quiero extenderlo bastante más, mejorarlo, añadir más efectos… pero para ilustrar creo que sobra.
Este código se distribuye bajo la licencia del MIT (MIT License: http://www.opensource.org/licenses/mit-license.php), por lo tanto hay que mantener el copyright de la cabecera.
PD: Aún no tengo implementado MooTools en el blog y no hay demo pero pronto pondré alguna.
Demo
Demo y tests en MooShell:
http://mootools.net/shell/XaUJA/3/.
MooShell iframe
Por si no resultará obvio: pulsa en la pestaña RESULT para ver el resultado de la demo.
TODO
- Cada ítem debe tener su propia altura si los ítems no tienen la misma.
Acerca del autor
J.A.Cobo, «Geek» apasionado por la tecnología, la historia y la aviación con especial interés en el Desarrollo Web basado en estándares, la aplicación semántica de la web y la accesibilidad en la misma. Hubo un tiempo en el que también escribía relatos, principal inspiración para iniciar un «blog».
- No hay comentarios.
- TrackBack URL
Aún no hay comentarios.
Dejar un comentario.no seas tímido