JMiur [E]

Sigo con la idea de mostrar y ocultar gadgets agregados a la sidebar de Blogger y ahora, le quiero poner alguna variante que produzca alguna clase de efecto. Ya se sabe que si usamos librerías de alguna clase, estas animaciones son cosas que suelen estar previstas pero, uno quiere eludir eso y en lo posible, hacerlo a mano porque de ese modo, es fácilmente aplicable a cualquier tipo de sitio y en el camino de re-inventar la rueda, algo se va aprendiendo.

Voy a usar el mismo esquema de la entrada anterior para crear ese efecto usando transiciones así que, desde ya, ese efecto no será visible en Internet Explorer pero, el sistema seguirá funcionando perfectamente así que no hay motivo para no intentarlo.

Lo que hacen las transiciones es animar el cambio de una propiedad; es decir, si algo es de color rojo y cambia a color azul, ese cambio no será instantáneo sino que durará cierto tiempo creándose estados intermedios y el color virará desde un rojo a un azul produciendo un efecto de animación. El problema a resolver en este caso es que si permutamos entre display:none y display:block no hay estados intermedios; algo se ve o no se ve y no hay otra posibilidad. Necesitamos usar alguna otra propiedad que podamos variar poco a poco y la única que sirve para eso es height. Esto sería sencillo si funcionaran los porcentajes pero, no es así, hay que saber la altura exacta y expresarla en pixeles.

Cualquier etiqueta de bloque a la que le ponemos la propiedad overflow:hidden y establecemos el valor de height, no se mostrará "completa" si su contenido supera ese valor:

Vivamus adipiscing luctus leo! Integer non elit quam. Donec nisi enim, feugiat id dapibus at, dictum vitae metus? Mauris nisi lorem, porta ut tincidunt ac, semper non lectus. Sed libero ligula; luctus id rutrum sit amet, interdum sit amet odio. Vestibulum varius ligula ac erat tempus commodo.
Vivamus adipiscing luctus leo! Integer non elit quam. Donec nisi enim, feugiat id dapibus at, dictum vitae metus? Mauris nisi lorem, porta ut tincidunt ac, semper non lectus. Sed libero ligula; luctus id rutrum sit amet, interdum sit amet odio. Vestibulum varius ligula ac erat tempus commodo.
Vivamus adipiscing luctus leo! Integer non elit quam. Donec nisi enim, feugiat id dapibus at, dictum vitae metus? Mauris nisi lorem, porta ut tincidunt ac, semper non lectus. Sed libero ligula; luctus id rutrum sit amet, interdum sit amet odio. Vestibulum varius ligula ac erat tempus commodo.

Pero ¿cuál es el valor de height de una etiqueta? Si es una en particular y la medimos, perfecto pero, si luego cambia, habrá que cambiar todo así que hay que buscar alternativas.

Hay un dato que nos da JavaScript: el alto de cualquier elemento visible. Ese dato se lee con clientHeight pero, el elemento debe estar visible y si está visible se arruina el efecto así que lo que se me ocurre es cargarlo fuera de la ventana del navegador, guardar su altura y luego moverlo a su lugar pero dándole una altura de cero con lo cual, quedará oculto.

¿Complicado? Hay más. A esto le sumamos otro problema. Hay gadgets que varían de tamaño cuando interactuamos con ellos. Por ejemplo, el de Archivos que se expande y contrae mostrando más o menos resultados, Si no contemplamos eso, hay partes que quedarán ocultas así que, de alguna manera, hay que detectar esos cambios, permitirlos y volver a re-calcular la altura.

Todo eso, hay que dejárselo al script para que lo que nosotros debamos modificar en la plantilla sea lo mínimo posible.

Voy a hacer lo mismo que hice antes, voy a agregarle una clase a la etiqueta H2 del título y unac clase al DIV inferior de cualquier gadget:
<h2 class='expcon'><data:title/></h2>
<div class='widget-temp'>
  ..............
</div>
Ahora, voy a poner el CSS básico donde es importante establecer el ancho que es el ancho libre de nuestra sidebar:
<style>
h2.expcon {cursor: pointer;}
.widget-con {
  height: 0px;
  width: 250px;
  overflow: hidden;
  -moz-transition: height 1s;
  -webkit-transition: height 1s;
  -o-transition: height 1s;
  transition: height 1s;
}
.widget-temp {
  position:absolute;
  left: -5000px;
  width: 250px;
}
</style>
Uso dos clases, widget-temp es la original, la del gadget sacado de la pantalla; cuando se calcula y se guarda la altura, se "vuelve" a su lugar cambiándole la clase por widget-con.

Aquí hay dos ejemplos simulaciones; el de la izquierda sería un gadget de altura estática y el de la derecha posee enlaces internos que pueden expandirse y colapsarse de manera independiente:

primer ejemplo

Aenean sed est sit amet dolor pellentesque ullamcorper. Mauris ac sapien vel nibh scelerisque tincidunt. In ac nisl quis leo dapibus gravida at id quam. Donec eget nisi nec purus accumsan gravida. Fusce imperdiet sem eu quam sagittis porta. Maecenas luctus porttitor sem in venenatis. Nullam fermentum euismod tristique. Sed massa lorem, pellentesque non malesuada eu; dignissim sed mauris. Etiam venenatis dictum dolor id vestibulum? Cras euismod; lacus a laoreet laoreet, justo magna porta ante, a lobortis nisi neque in lectus. Nam ultricies aliquet mauris at dictum. Proin dapibus velit quis nibh tristique dapibus.

segundo ejemplo

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.

expandir/contraer [+]
expandir/contraer [+]

Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.


Y acá está el script con algunas explicaciones:

<script type='text/javascript'>
//<![CDATA[

// agrega un ID a la etiqueta si se usa Internet Explorer: http://www.codingforums.com/archive/index.php/t-125144.html
var IEelem={};
function IEaddID(fn,uniqueID) {
  return function(event) {return fn.call(IEelem[uniqueID],event);}
}

// esta es la función que agregará el evento onclick
function agregarEVENTOtogglewidget() {
  // creo una lista con todas las etiquetas H2
  var el = document.getElementsByTagName("h2");
  // leo la lista una por una
  for (var i=0; i<el.length; i++) {
    var c = el[i].className; // guardo el contenido del atributo class expcon
    // si es una etiqueta H2 con la clase que definí, le agrego un evento que ejecute una función a la que llamo togglewidget
    if (c=="expcon") {
      if (el[i].addEventListener) {
         // Firefox, Chrome, Opera, IE9
        el[i].addEventListener("click", togglewidget, false);
      } else if (el[i].attachEvent) {
        // Internet Explore 8
        var uniqueID = el[i].uniqueID;IEelem[uniqueID] = el[i];
        el[i].attachEvent("onclick",IEaddID(togglewidget,uniqueID));
      }
      // busco la etiqueta DIV
      var obj = el[i].nextElementSibling || el[i].nextSibling;
      obj.altura = obj.clientHeight; // guardo su altura
      obj.className = "widget-con"; // le cambio la clase
      obj.style.height = "0px"; // la oculto
      // y agrego otro evento a ese DIV de tal forma de poder recalcular su altura cuando cambie
      if (obj.addEventListener) {
        obj.addEventListener("click", recalcular, false);
      } else if (el[i].attachEvent) {
        var uniqueID = obj.uniqueID;IEelem[uniqueID] = obj;
        obj.attachEvent("onclick",IEaddID(recalcular,uniqueID));
      }
    }
  }
}

// esta es la función que permuta el contenido
function togglewidget() {
  // hice click en la etiqueta H2 pero, debo ocultar la etiqueta DIV que es la siguiente; así que a busco:
  var obj = this.nextElementSibling || this.nextSibling;
  if(obj.style.height=="0px") {
    // esta oculta así que la muestro
    obj.style.height = obj.altura + "px";
  } else {
    // esta visible así que la oculto
    obj.style.height = "0px";
  }
}

// esta es la función que recalcula la altura
function recalcular() {
  // se pone al 100% para permitir que se expanda verticalmente
  this.style.height = "100%";
  // se ejecuta una demora para que se efectivice ese cambio
  // cambiar 200 por un número mayor si el contenido es "pesado"
  var _this = this;
  setTimeout(function() {
    // y se guarda la nueva altura
    _this.altura = _this.clientHeight;
    _this.style.height = _this.altura + "px";
  }, 200);
}

// una vez que la página web se carga, ejecuto la función
onload=function() { agregarEVENTOtogglewidget(); }

//]]>
</script>

34 comentarios:

egoloco  

Bastante funcional, pero... que largo que es el script!!! Aunque es interesante tomarse el trabajo de reajustar el diseño para cada plantilla. Eso me gusta. Lo guardo por si alguna vez me sirve. Gracias JMiur!

Responder
JMiur  

Los scripts no deben "medirse" por la cantidad de líneas que poseen sino por su velocidad o incluso, por su funcionalidad. Pueden tener dos líneas y ser lentos o tener 100 y ser rápidos; depende.

Responder
Beben Koben  

great combine javascript with code template blogspot...
co creative :)

Responder
k_nelita  

Hola JM, hace rato que tengo pendiente el cambiar el javascript que uso para contraer el gadget del Feedjit, te acordás que te dije que en IE9 se ve mal, o sea se ve cuando debe estar oculto.
Pero no se si esto me puede servir, me gusta el efecto deslizante pero lo de la altura no me va a dar, ya que el Feedjit cambia, a veces es mas largo y otras mas corto...
Que opinás? Que otro puedo usar que sea sencillo para que la gente no lo vea, es el único gadget que quiero ocultar en http://www.sonando-porbailar.com.ar ahora mismo está con el script de siempre, en Chrome y FireFox se ve bien, pero en IE9 no... :S

Responder
JMiur  

Este script hace justamente eso, no tener en cuenta la altura sino calcularla y de ese modo, cuando algo varia, nos desentendemos del asunto.

Lo que no puedo decirte es si funciona o no funciona en IE9.

Otra alternativa es usar librerías como jQuery pero, tampoco hay garantias de que funcionen y son bastante más pesadas.

Responder
k_nelita  

A ver si entiendo... la primer parte, la que dice h2 y termina en div, al principio de todo, también tengo que ponerlo o solo copio lo que sigue todo completo, estilos y script no?
Y el título cual sería o donde iría?

Responder
JMiur  

h2 es el título, tal como existe ahora en cualquier sidebar; sól ose le agrega el atributo class='expcon'

El siguente DIV envuelve todo el resto del código así qe luego del título va:

<div class='widget-temp'>

y al fina del includable va:

</div>

Responder
k_nelita  

Pero eso ya está incluído en los estilos de mas abajo o entendí mal?
Son las tres partes que tengo que poner o solo las dos últimas, es decir estilos y script?

Responder
JMiur  

Me perdi :D

EL HTML es una cosa, es eso que se debe modificar en el gadget.

El script y el estilo son para que funcione.

Responder
Ezeguko  

JMiur, en alguna entrada explicás como hacer como vos tenés en tu blog como se muestran las entradas? Es decir, que la primera se vea entera y que el resto resumidas...

¡Saludos! :D

Responder
JMiur  

Eso está explicado en estas tres entradas: 1 | 2 | 3

Responder
Ezeguko  

¡Gracias, JMiur!

Responder
k_nelita  

Es fácil perderse cuando trato de explicar algo sin poder poner acá los códigos :S

Pero ayer estaba mirando los otros blogs donde tengo el mismo script de expandir y contraer o como se llame, y en todos funciona bien con IE9, el único que no funciona (en cualquiera de los blogs) es el que contiene el script del Feedjit, sospecho que es eso lo que no funciona en IE9, no quiere ocultarse y sale todo ensimado con el resto de las cosas de la sidebar...

Es una pena que no puedas verlo, lo estoy usando en Directorios, Amigos, etc y funciona en todos los blogs, pero con el Feedjit no...

No creo que te sirva una captura no? Solo verías el efecto pero si no tenés IE9 no lo podés ver "trabajando" (por llamarlo de alguna forma).
Se te ocurre algo?

El script que tengo está en http://www.propon.com.ar (acá hay varios) y en http://www.sonando-porbailar.com.ar que solo está el del Feejit.

No quisiera tener que prescindir de ese gadget ya que me muestra bastante bien el tráfico de los blogs...

Responder
JMiur  

No, a menos que pueda verlo no hay nada que pueda decirte. No sé que puede ser lo que no funcione o lo afecte.

Responder
k_nelita  

Hola JM, hoy me puse a experimentar, en realidad anoche cuando me iba a acostar empecé a idear esto en mi cabeza jajja y hoy lo probé.
Hice un página, de las estáticas se llaman no? Y ahí metí el Feedjit mandé el enlace a la sidebar y lo miré en IE9 y se ve bien, o sea no se ve mas que el enlace y al entrar me lleva al Feedjit, y ya lo hice en los dos blogs, el único inconveniente o molestia por así llamarlo es que no puedo poner target_blank para que abra en ventana aparte... pero logré que no se despatarrara la sidebar con mi chapucería, que opinás?
Y puedo checar mis visitas de allí aunque tenga que entrar al link y me saque del blog... Algo es algo jajja :D

Otra inquietud que tengo y que hoy me di cuenta es que en el segundo blog que te menciono en el otro post, la sidebar en Chrome, tiene bordes redondeados, en FireFox también, pero en IE9 no, se ve cuadrado...
Me está preocupando este navegador ya que estoy viendo que cada día mas gente lo utiliza, y yo trabajo todo con Chrome, abandoné mi querido FF cuando vi que Chrome era mucho mas rápido.
Por eso reviso todo con estos tres navegadores y el IE9 siempre me da algún problema... :S

Responder
JMiur  

Si el CSS utiliza propiedades de tipo -moz-border-radius o -webkit-border-radius no funcionará en IE9 ya que la propiedad geerica y adaptada para todos los navegadores es border-radius, sin los prefijos.

Responder
k_nelita  

Tiene -moz-border-radius y
-webkit-border-radius los dos, vos decís que le agregue border-radius o que los cambie?
Al final este IE tan nuevo que es tiene mas vueltas...

Responder
JMiur  

En principio,yo los elimianaria y dejaría sólo border-radius porque quienes usan Firefox y Chrome (los prefijos son apra esos navegadores) los tienen actualizados y por lo tanto, los prefijos ya son innecesarios y border-radius ya es una propiedad genérica y aceptada, incluyendo IE9.

Responder
k_nelita  

Bueno JM gracias, voy a ver si no es muy engorroso para hacerlo ahora mismo antes que me de mas sueño :)
Mil gracias :)

Responder
k_nelita  

No pude... :( saqué todos los border radius que encontré, bueh los otros, y los cambié por border-radius pero IE no los quiere o no se que pero se sigue viendo cuadrado :S Vos ves alguno que yo no vea?
O lo tendré que modificar desde el mismo IE?

Responder
JMiur  

Como te dije, al no poder usar ese navegador, no sabría contestarte el motivo.

Responder
k_nelita  

Pero en IE8 como lo ves? O en al código fuente ves alguno que se me haya escapado a pesar de que lo revisé mil veces?

Responder
JMiur  

En IE8, border-radius no funciona.

Responder
k_nelita  

No me resultó la chapuza de meter el Feedjit en una página estática :( No funciona... al parecer tiene que estar en la home para que marque las visitas buaaa...
Si lo pongo en la sidebar se me hace muuuuy larga, esconderlo con un script no puedo porque IE no lo oculta con ninguno :'(

Y con respecto al tema del border-radius, me decís que IE no lo reconoce? Entonces ningún IE ve los bordes redondeados? De ninguna forma?

Responder
JMiur  

IE9 si, IE8 no.

Responder
Ros  

Quiero hacer que en vez de que el div se deslize hacia abajo se deslize hacia arriba, como se puede hacer?

Saludos

JMiur  

No sé. Tendrás que pensar conceptualmente como hacer eso porque no puede hacerse cambiando la altura del elemento.

Responder
Ros  

Jmiur, ¿como podria configurarlo para que aparezca abierto?

JMiur  

Tal vez, cambiando el height: 0px; inicial del CSS pero, como no está pensado para que funcione de ese modo, no podría asegurarlo.

Responder
SergioFM  

Muy interesante pero no entendí mucho.
Exactamente en qué parte de la plantilla debo aplicar el script? y cómo haré para aplicar la función al gadget deseado?

JMiur  

El script lo puedes colocar com ocualqueir otro, antes de <head>

Para usarlo en un gadget, debes editarlo según indica la entrada.

Sergio Flores Maldonado  

Después de mucho.... volví a intentarlo y esta vez lo he logrado. Gracias!

Responder
Photonica  

No me funciona con el gadget de seguidores, ni tampoco es compatible con el gadget de etiquetas cuando éstas están divididas en 2 columnas ¿a qué se puede deber?

Gracias.

JMiur  

Dependerá de cómo esté armado el HTML/CSS; sin ver un ejemplo es imposible saberlo.

Responder

¿Quiere dejar un comentario?

recuerde que los comentarios están siendo moderados y serán publicados a la brevedad ...

Todos los archivos y demos alojados en Fileden han sido redireccionados y deberían estar funcionando correctamente.
De todos modos, también puede accederse a ellos a través de SkyDrive

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 ...

 
CERRAR