Como siempre, hay muchas formas de hacer esto así que vamos con una muy elemental; vamos a utilizar una lista donde en cada item colocaremos una imagen en una etiqueta IMG y un texto en una etiqueta SPAN; cada imagen será, en este caso, de 300x190:
<style> .contenedor { /* el DIV que contendrá todo */ height: 250px; margin: 0 auto; width: 300px; } ul#demoanim { /* la lista con las imágenes y los textos */ height: 220px; margin: 0 auto; overflow: hidden; /* forzamos a que se oculte todo excepto una imagen */ position: relative; /* posicionamos la lista de manera relativa */ text-align: center; width: 300px; } ul#demoanim li { /* cada item de la lista */ list-style-type: none; position: absolute; /* los posicionamos de manera absoluta */ left: 0; top: 0; visibility: hidden; /* y los ocultamos momentáneamente */ } ul#demoanim li img { /* formazos a que las imágenes sean todas iguales */ height: 190px; width: 300px; } ul#demoanim li span { /* el texto inferior con cualquier tipo de formato */ display: block; } .navdemoani { /*a navegación inferior */ text-align:center; } .navdemoani a { /* los enlaces de navegación */ } </style> <!-- pongo todo dentro de un DIV --> <div class="contenedor"> <! -- la lista con imágenes --> <ul id="demoanim"> <li<img src="URL_imagen_1" /><span> la primera de las imagenes </span></li> <li><img src="URL_imagen_2" /><span> la segunda imagen </span></li> <li><img src="URL_imagen_3" /><span> la tercera imagen </span></li> <li><img src="URL_imagen_4" /><span> la cuarta imagen </span></li> <li><img src="URL_imagen_5" /><span> la última imagen </span></li> </ul> <!-- los enlaces para avanzar y retroceder --> <div class="nav"> <a href="javascript:animdemo(1);">anterior</a> | <a href="javascript:animdemo(-1);">siguiente</a> </div> </div>
Necesitaríamos posicionarlas una al lado de la otra y guardar eso en alguna parte porque, justamente, esa posición es la que vamos a cambiar de manera dinámica y lo que creará el efecto de desplazamiento. El resultado, aunque no se vea, será una tira larga de imágenes, así que si sé que miden 300 pixeles de ancho, la primera debería tener la propiedad left:0px, la segunda left:300px, la tercera left:600px, etc. Si luego de eso las hago visibles, sólo veré la primera porque para eso usé el overflow:hidden.
Podría cambiar el HTML y poner ese dato en cada etiqueta LI pero no tengo ganas de hacer cuentas así que aprovechamos JavaScript para que lo haga por nosotros y de paso, que guarde los datos para que luego podamos manipularlos.
No sé la cantidad de imágenes que hay, no tienen ID, sólo conozco el ID de la lista pero las etiquetas LI no tienen; sin embargo, puedo leer esos datos usando la función getElementsByTagName() que lo que hace es "buscar" las etiquetas HTML que se le indiquen así que le digo que busque dentro del ID que conozco, todas las etiquetas LI que haya:
var listaani = document.getElementById("demoanim").getElementsByTagName("li");
De ese modo, listaani[0] tendrá todos los datos de la primera etiqueta LI, listaani[1] los datos de la segunda, listaani[2] los de la tercera, etc.
Así que, debajo de lo que habíamos hecho, agrego algo así:
<script> anchoanimdemo = 300; // es el ancho de las imagenes // voy a guardar cada etiqueta LI en un array var listaani = document.getElementById("demoanim").getElementsByTagName("li"); // listaani.length me dirá la cantidad de elementos (cuántas imágenes hay) // hago un bucle y voy agregando las propiedades a cada una de ellas for(var i = 0; i < listaani.length; i++){ // la posicion left es pura aritmética: 0*300=0; 1*300=300; 2*300=600; etc listaani[i].style.left = (i * anchoanimdemo) + "px"; listaani[i].style.visibility= "visible"; } </script>
<script type='text/javascript'> //<![CDATA[ // voy a inicializar algunas variables var timeranimdemo; // el nombre que le daré al timer var timerFLAGanimdemo = 0; // un valor que me indicará si estoy aumentando (1) o disminuyendo (-1) la posición var contadoranimdemo; // es lo que usaré para saber cuando detenerme var imagenanimdemo = 0; // el número de orden de las imágenes (de las etiquetas LI que guardamos en listaani[] ) var velocidadanimdemo = 1; // lo usaré para controlar la velocidad del slider var anchoanimdemo = 300; // es el ancho de las imágenes // esta función es la que se ejecuta al hacer click en los enlaces de la navegación // en la dirección habrá un valor de 1 para indicar que se moverá hacia la derecha y un valor de -1 para moverse hacia la izquierda function animdemo(direccion) { // si el flag no es cero quiere decir que se está animando así que salimos de la función para no ejecutarla varias veces if(timerFLAGanimdemo!=0) { return; } // verifico que haya más imágenes if(direccion==-1 && imagenanimdemo==(listaani.length-1)) { // click en anterior pero estoy en la primera imagen asi que no hago nada return; } if(direccion==1 && imagenanimdemo==0) { // click en siguiente pero estoy en la última imagen asi que no hago nada return; } // todo está OK así que inicializo el efecto contadoranimdemo = 0; // pongo a cero el contador timerFLAGanimdemo = direccion; // guardo la dirección // indico que la función timerejemploanimdemo() se ejecute cada milisegundo timeranimdemo = setInterval(timerejemploanimdemo,1); } // y esta es la función que se ejecutará una vez cada milisegundo function timerejemploanimdemo() { contadoranimdemo++; // incrementamos el contador // calculo cuántos pixeles se deben despazar (si la velocidad es 1 y la imagen mide 300, serán 300) // si el contador llegó hasta ese valor, detenemos todo if(contadoranimdemo>(anchoanimdemo/velocidadanimdemo)) { // cancelamos la función y ya no se seguirá ejecutando clearTimeout(timeranimdemo); // guardo el número índice de la imagen que está visible imagenanimdemo = imagenanimdemo - timerFLAGanimdemo; // terminamos la animación timerFLAGanimdemo = 0; return; } // con un bucle, modifico la propiedad left, sumando o restando una cantidad de pixeles for(var i = 0; i < listaani.length; i++){ posicionactual = parseInt(listaani[i].style.left) + timerFLAGanimdemo * velocidadanimdemo; listaani[i].style.left = String(posicionactual) + "px"; } } //]]> </script>
4 comentarios:
Bravo!!! :)
Tengo una duda. La clase .contenedor no entrará en conflicto con otra clase del mismo nombre que pudiera tener el blog, definida para otro script?
Grande Jmiur, ya probaré :D
Esto se esta poniendo cada vez mejor. Vamos a probrarlo.
Por casualidad me ocurre a mi solo que por momentos se traba el slide? o es probable que ocurra?
Manfenix:
Si, eso puede ocurrir. Simplemente, coloca cualquier otro nombre de clase o de ID.
Graciela:
Pruebe :D
Adrián:
Si. eso puede ocurrir. Mejor dicho, ocurrirá ya que se mueve pixel por pixel, y no hay una optimización del código o del bucle ya que sólo se trata de un demo.
¿Quiere dejar un comentario?
recuerde que los comentarios están siendo moderados y serán publicados a la brevedad ...
Nota: sólo los miembros de este blog pueden publicar comentarios.
Si le gusta ir a lo seguro utilice este botón para abrir los comentarios en una ventana modal en esta misma pagina.
Si añora tiempos idos, use este enlace para agregar un comentario al viejo estilo ...