Spotlight Stickies restringidos con jQuery

Cada dos semanas, vamos a echar un vistazo ultra centrado a un efecto interesante y útil, plugin, hack, biblioteca o incluso una tecnología ingeniosa. Luego intentaremos deconstruir el código o crear un pequeño proyecto divertido con él.

Hoy, vamos a echar un vistazo a un complemento que implementa un efecto bastante bueno. Es bastante difícil de explicar en una oración, por lo que también puede hacer clic en el botón Continuar para comenzar después del salto..


Una palabra del autor

Como desarrolladores web, tenemos acceso a una asombrosa cantidad de código preconstruido, ya sea un pequeño fragmento de código o un marco completo. A menos que esté haciendo algo increíblemente específico, lo más probable es que ya haya algo creado previamente para que lo aproveche. Desafortunadamente, muchas de estas ofertas estelares languidecen en el anonimato, especialmente para la multitud no hardcore..

Esta serie busca corregir este problema mediante la introducción de un código útil y bien escrito, ya sea un complemento, un efecto o una tecnología para el lector. Además, si es lo suficientemente pequeño, intentaremos deconstruir el código y entender cómo lo hace vudú. Si es mucho más grande, intentaremos crear un mini proyecto con él para aprender las cuerdas y, con suerte, entender cómo usarlo en el mundo real..


Introduciendo stickyFloat

Aquí hay alguna información rápida:

  • Tipo: Enchufar
  • Tecnología: JavaScript [Construido en la biblioteca jQuery]
  • Función: Contenido flotante solo dentro de las restricciones de los límites de sus padres
  • Página de inicio del plugin: aquí

El problema

En muchos casos, necesita que el contenido esté flotando a medida que se desplaza, pero solo dentro de su padre.

El contenido flotante mientras un usuario se desplaza por el resto de la página es un juego de niños. No es necesario tener JavaScript, puedes hacerlo solo con CSS antiguo. Una bofetada posición: fijo ¡Declaración y boom !, tienes un contenedor que está arreglado en una ubicación específica de la página; está flotando en la página para ser más coloquial.

Pero seamos sinceros, no funciona con todos los diseños. Podría planear un poco más adelante y colocarlo en la página para que nunca interfiriera con elementos importantes, pero no sería completamente infalible ni reutilizable en ningún otro lugar sin grandes cambios..

En estos casos, necesita que el contenido esté flotando a medida que se desplaza, pero solo dentro de su padre.. Si se está preguntando, sí, esta funcionalidad es una variación de la que Andrew le mostró en el tutorial de la semana pasada, que es cómo me enteré de este complemento..

Como encontrará en el desarrollo web, al igual que el cálculo multivariable, a menudo hay una serie de soluciones para cualquier problema dado. Veamos una de esas soluciones alternativas..


Deconstruyendo la lógica

La lógica general o el flujo de trabajo del enchufe es en realidad bastante simple. Deja que te enseñe. Tenga en cuenta que me referiré al elemento que debe flotar como pegajoso de ahora en adelante.

Pero antes de comenzar, aquí hay una rápida maqueta para mostrar la jerarquía:

La lógica completa del complemento se puede diluir hasta:

  • Calcula la posición actual del elemento pegajoso. padre, relativo al documento. Marcado como 1 en la imagen..
  • Obtener la altura de los padres también - Así que sabremos cuándo dejar de flotar cuando hayamos pasado al padre. Marcado como 2.
  • Calcule hasta qué punto se ha desplazado la página hacia abajo - Para saber si estamos mirando a los padres, para ver si estamos dentro del rango. En la imagen de arriba, la línea horizontal marca la parte superior hipotética de la ventana gráfica actual. En este caso, este valor será la distancia entre los puntos marcados como 3.
  • Usando los dos valores que hemos calculado anteriormente, podemos descubrir muy rápidamente si es necesario reposicionar adecuadamente el adhesivo.

Si estás confundido, no lo estés. Por ejemplo, veamos algunos números de muestra:

  • El padre del sticky está presente. 10px desde la parte superior de la página.
  • El padre es 100px alto.
  • La página ha sido desplazada 50px en un escenario y 150px en el otro.

Así que en base a esta información anterior, puedes deducir que

En el escenario uno - el pegajoso debe ser re-flotado adecuadamente. ¿Por qué? La página ha sido desplazada 10px desde la parte superior: 10 proviene de la propia página, mientras que el resto proviene de la matriz del sticky. Por lo tanto, el padre es visible en la ventana principal.

En el escenario dos - El pegajoso se puede dejar solo. De los 150px, 10 provienen de la página, 100 del elemento padre y el resto es ocupado por el resto del elemento de la página. Esto implica que el usuario se ha desplazado más allá del padre y no necesitamos hacer nada..

Si todavía estás confuso en este punto, no te preocupes. Te explicaré un poco más mientras caminas por la fuente..


Deconstruyendo la Fuente

La fuente eliminada de comentarios es solo un fragmento de más de 30 líneas. Como siempre, revisaremos el código y explicaremos qué hace cada línea..

Aquí está la fuente, para su referencia.

 $ .fn.stickyfloat = function (options, lockBottom) var $ obj = this; var parentPaddingTop = parseInt ($ obj.parent (). css ('padding-top')); var startOffset = $ obj.parent (). offset (). top; var opts = $ .extend (startOffset: startOffset, offsetY: parentPaddingTop, duración: 200, lockBottom: true, opciones); $ obj.css (position: 'absolute'); if (opts.lockBottom) var bottomPos = $ obj.parent (). height () - $ obj.height () + parentPaddingTop; si < 0 ) bottomPos = 0;  $(window).scroll(function ()  $obj.stop(); var pastStartOffset = $(document).scrollTop() > opts.startOffset; var objFartherThanTopPos = $ obj.offset (). top> startOffset; var objBiggerThanWindow = $ obj.outerHeight () < $(window).height(); if( (pastStartOffset || objFartherThanTopPos) && objBiggerThanWindow ) var newpos = ($(document).scrollTop() -startOffset + opts.offsetY ); if ( newpos > bottomPos) newpos = bottomPos; if ($ (document) .scrollTop () < opts.startOffset ) newpos = parentPaddingTop; $obj.animate( top: newpos , opts.duration );  ); ;

Es hora de ver lo que realmente hace. Voy a asumir que tienes un conocimiento bastante básico de JavaScript..

 $ .fn.stickyfloat = function (options, lockBottom) ;

Paso 1 - El contenedor genérico para un plugin jQuery. Como probablemente sabes, opciones es un objeto que contiene una variedad de opciones para configurar el comportamiento del complemento. LockBottom, Curiosamente, especifica si la funcionalidad que queremos está activada o no. Lo dejaremos encendido.

 var $ obj = esto;

Paso 2 - Mantener una referencia al elemento pasado. En este contexto, esta apunta al elemento DOM que coincide con el selector que ha pasado. Por ejemplo, si pasó #menú, esta apunta al elemento con ese ID.

 var parentPaddingTop = parseInt ($ obj.parent (). css ('padding-top'));

Paso 3 - Esto es solo para suavizar el efecto si el elemento principal tiene un relleno grande. Si es así, esto incluirá el relleno en el cálculo..

 var startOffset = $ obj.parent (). offset (). top;

Etapa 4 - Calculamos la posición de los padres en relación con el documento utilizando el compensar Método jQuery. Trabajamos a través del DOM usando el padre método. Nosotros $ obj ya que ya hemos cacheado el pegajoso. Acceda a la documentación de la API de jQuery si no está familiarizado con estos métodos..

En este caso, la distancia desde la parte superior es suficiente, por lo que adquiriremos ese valor solo.

 var opts = $ .extend (startOffset: startOffset, offsetY: parentPaddingTop, duración: 200, lockBottom: true, opciones);

Paso 5 - Una parte bastante genérica del proceso de desarrollo del complemento jQuery. Básicamente, nos fusionamos en las opciones aprobadas junto con algunos ajustes preestablecidos para obtener un conjunto final de opciones que se utiliza en todo el código. Tenga en cuenta que los parámetros pasados ​​siempre tienen prioridad sobre los valores predeterminados.

 $ obj.css (position: 'absolute');

Paso 6 - El efecto en cuestión se creará manipulando el elemento parte superior Valor de CSS, así que seguiremos adelante y estableceremos su posición en absoluta en caso de que aún no se haya configurado de esa manera.

 if (opts.lockBottom) var bottomPos = $ obj.parent (). height () - $ obj.height () + parentPaddingTop; si < 0 ) bottomPos = 0; 

Paso 7 - Como se señaló anteriormente, el LockBottom La opción especifica si el efecto en cuestión funciona o no. Si está habilitado, podemos empezar a calcular. Lo que estamos calculando es el punto de corte más allá del cual no necesitaríamos reposicionar el adhesivo.

Naturalmente, puede ir simplemente calculando la altura del padre pero el efecto no será refinado. Tendrá que tener en cuenta la altura del adhesivo a lo largo de los rellenos del propio padre.

 $ (ventana) .scroll (function () // Lotes de código)

Paso 8 - Enganchamos nuestro código, dentro de una función anónima, a las ventanas voluta evento. Por supuesto, esta no es la forma más eficiente de proceder, pero lo ignoraremos por ahora..

 $ obj.stop ();

Paso 9 - El primer orden de la palabra es detener todas las animaciones en ejecución en el elemento adhesivo. los detener El método se encarga de esto..

 var pastStartOffset = $ (document) .scrollTop ()> opts.startOffset; var objFartherThanTopPos = $ obj.offset (). top> startOffset; var objBiggerThanWindow = $ obj.outerHeight () < $(window).height();

Paso 10 - Estas tres variables mantienen valores que usaremos un poco más adelante..

  • pastStartOffset comprueba si hemos desplazado más allá del límite superior del elemento padre. Recuerda, usamos el compensar Método para averiguar el espacio entre el elemento padre y el documento. Obtenemos hasta qué punto ha desplazado hacia abajo utilizando el scrollTop método. Esta es la distancia entre la parte superior del documento y la parte superior de la ventana gráfica actual.
  • objFartherThanTopPos comprueba si el adhesivo está en su posición predeterminada, en la parte superior de su padre. Si nos hemos desplazado más allá de la parte superior del padre, no lo queremos flotando afuera.
  • objBiggerThanWindow verifica si la altura total del adhesivo es más grande que el tamaño de la ventana. Si ese es el caso, no tiene sentido manipular el elemento pegajoso.
 if ((pastStartOffset || objFartherThanTopPos) && objBiggerThanWindow) // Más código

Paso 11 - Aquí es donde el complemento calcula si necesitaremos manipular el elemento adhesivo. Lo que la línea anterior lo hace:

  • Compruebe si el usuario está desplazando exactamente en el rango del elemento padre. Verificamos si el usuario está por debajo del límite superior del padre o, alternativamente, el adhesivo está en la parte superior.
  • Como se indicó anteriormente, procedemos solo si el adhesivo es más pequeño que el tamaño de la ventana.

Procedemos solo si ambos de estas condiciones se cumplen.

 var newpos = ($ (document) .scrollTop () -startOffset + opts.offsetY);

Paso 12 - Esta línea define una variable., Newpos, que especifica la posición en la que se debe animar el elemento adhesivo. Como habrá notado, el cálculo es bastante básico si se tiene en cuenta la imagen de arriba. Averigüe la distancia desplazada, agregue el relleno superior del padre y finalmente reste la distancia entre el documento y el padre: el punto de partida. Esto le da la distancia, en píxeles, entre la parte superior del elemento principal y el punto interior, donde debe colocarse el adhesivo.

 if (newpos> bottomPos) newpos = bottomPos;

Paso 13 - Si nos hemos desplazado más allá del límite inferior del elemento padre, no es necesario manipular más las cosas. Bloquear su posición allí.

 if ($ (document) .scrollTop () < opts.startOffset ) newpos = parentPaddingTop;

Paso 14 - Si nos hemos desplazado por encima del límite superior del padre, manténgalo bloqueado allí para que no se mueva más hacia arriba.

 $ obj.animate (top: newpos, opts.duration);

Paso 15 - ¡Todo listo! Simplemente animamos el elemento pegajoso pasando el requerido. parte superior valor junto con la duración del efecto utilizando el animar metodo jQuery.


Uso

Como es probable que haya inferido en este punto, el uso es así:

 $ ('# menu'). stickyfloat (duration: 500);>

En lugar de explicar el mini-proyecto de ejemplo, como la última vez, decidí simplemente compilarlo y darle el código.

Aquí están las partes relevantes de la demostración, el resto es repetitivo:

El HTML

 
Menú pegajoso
Quería escribir algo increíblemente, descaradamente ingenioso aquí. Fallé. :(
Sí, te seguiré a todas partes mientras estés dentro de mi padre
Estabas esperando algo inteligente aquí, ¿verdad? ¡Sé que lo hiciste! Fess hasta!

El CSS

 .sección relleno: 10px; ancho: 900px; margen: 0 auto; color de fondo: # f1f1f1; posición: relativa;  .section .content height: 800px; color de fondo: #ddd; margen izquierdo: 250px; text-align: center; color: # 333; tamaño de fuente: 16px;  .sección .menu posición: absoluta; izquierda: 10px; ancho: 240px; altura: 100px; fondo: # 06C; text-align: center; color: #fff; tamaño de fuente: 14px; 

El JavaScript

 $ ('# menu'). stickyfloat (duration: 400); $ ('# menu2'). stickyfloat (duration: 400);

Si está revisando los archivos mientras lee este artículo, debería explicarse por sí mismo, pero es más que bienvenido si tiene alguna duda sobre cualquier parte.


Terminando

Y hemos terminado. Echamos un vistazo a un complemento increíblemente útil, recorrimos el código fuente y finalmente terminamos creando un mini proyecto con él..

Preguntas? Cosas bonitas que decir? Criticas? Pulsa la sección de comentarios y déjame un comentario. Muchas Gracias Por Leer!