jquery - left - sticky sidebar wordpress
Barra lateral adhesiva: pegue al fondo cuando se desplaza hacia abajo, hacia arriba cuando se desplaza hacia arriba (6)
Aquí hay un ejemplo de cómo implementar esto:
JavaScript:
$(function() {
var $window = $(window);
var lastScrollTop = $window.scrollTop();
var wasScrollingDown = true;
var $sidebar = $("#sidebar");
if ($sidebar.length > 0) {
var initialSidebarTop = $sidebar.position().top;
$window.scroll(function(event) {
var windowHeight = $window.height();
var sidebarHeight = $sidebar.outerHeight();
var scrollTop = $window.scrollTop();
var scrollBottom = scrollTop + windowHeight;
var sidebarTop = $sidebar.position().top;
var sidebarBottom = sidebarTop + sidebarHeight;
var heightDelta = Math.abs(windowHeight - sidebarHeight);
var scrollDelta = lastScrollTop - scrollTop;
var isScrollingDown = (scrollTop > lastScrollTop);
var isWindowLarger = (windowHeight > sidebarHeight);
if ((isWindowLarger && scrollTop > initialSidebarTop) || (!isWindowLarger && scrollTop > initialSidebarTop + heightDelta)) {
$sidebar.addClass(''fixed'');
} else if (!isScrollingDown && scrollTop <= initialSidebarTop) {
$sidebar.removeClass(''fixed'');
}
var dragBottomDown = (sidebarBottom <= scrollBottom && isScrollingDown);
var dragTopUp = (sidebarTop >= scrollTop && !isScrollingDown);
if (dragBottomDown) {
if (isWindowLarger) {
$sidebar.css(''top'', 0);
} else {
$sidebar.css(''top'', -heightDelta);
}
} else if (dragTopUp) {
$sidebar.css(''top'', 0);
} else if ($sidebar.hasClass(''fixed'')) {
var currentTop = parseInt($sidebar.css(''top''), 10);
var minTop = -heightDelta;
var scrolledTop = currentTop + scrollDelta;
var isPageAtBottom = (scrollTop + windowHeight >= $(document).height());
var newTop = (isPageAtBottom) ? minTop : scrolledTop;
$sidebar.css(''top'', newTop);
}
lastScrollTop = scrollTop;
wasScrollingDown = isScrollingDown;
});
}
});
CSS:
#sidebar {
width: 180px;
padding: 10px;
background: red;
float: right;
}
.fixed {
position: fixed;
right: 50%;
margin-right: -50%;
}
Demostración: http://jsfiddle.net/ryanmaxwell/25QaE/
Esto funciona como se espera en todos los escenarios y también está bien soportado en IE.
He estado buscando algo de tiempo para encontrar una solución a mi problema con la barra lateral adhesiva. Tengo una idea específica de cómo me gustaría que actúe; De hecho, me gustaría que se quedara en la parte inferior a medida que te desplazas hacia abajo, y tan pronto como te muevas hacia atrás me gustaría que se adhiera a la parte superior, en un movimiento fluido (sin saltos). No puedo encontrar un ejemplo de lo que estoy tratando de lograr, así que he creado una imagen que espero que ilustre el punto más claramente:
- La barra lateral se encuentra debajo del encabezado.
- A medida que se desplaza hacia abajo, la barra lateral permanece nivelada con el contenido de la página para que pueda desplazarse por la barra lateral y el contenido.
- Alcanza la parte inferior de la barra lateral, la barra lateral se pega a la parte inferior de la ventana gráfica (la mayoría de los complementos solo permiten adherirse a la parte superior, algunos que permiten adherirse al fondo no permiten ambos).
- Alcanza la parte inferior, la barra lateral se encuentra sobre el pie de página.
- A medida que retrocedes, la barra lateral se mantiene al nivel del contenido para que puedas desplazarte nuevamente por el contenido y la barra lateral.
- Alcanza la parte superior de la barra lateral, la barra lateral se pega a la parte superior de la ventana gráfica.
- Alcanza la parte superior y la barra lateral se sienta debajo del encabezado.
Espero que esto sea suficiente información. Creé un jsfiddle para probar cualquier plugin / scripts, que he reseteado para esta pregunta: http://jsfiddle.net/jslucas/yr9gV/2/ .
Estaba buscando exactamente lo mismo. Aparentemente tenía que buscar algunos términos oscuros solo para encontrar una pregunta similar con el gráfico. Resulta que es exactamente lo que estaba buscando. No pude encontrar ningún complemento así que decidí hacerlo yo mismo. Con suerte, alguien verá esto y lo refinará.
Aquí hay un html de muestra rápido y sucio que estoy usando.
<div id="main">
<div class="col-1">
</div>
<div class="col-2">
<div class="side-wrapper">
sidebar content
</div>
</div>
</div>
Aquí está el jQuery que hice:
var lastScrollPos = $(window).scrollTop();
var originalPos = $(''.side-wrapper'').offset().top;
if ($(''.col-2'').css(''float'') != ''none'') {
$(window).scroll(function(){
var rectbtfadPos = $(''.rectbtfad'').offset().top + $(''.rectbtfad'').height();
// scroll up direction
if ( lastScrollPos > $(window).scrollTop() ) {
// unstick if scrolling the opposite direction so content will scroll with user
if ($(''.side-wrapper'').css(''position'') == ''fixed'') {
$(''.side-wrapper'').css({
''position'': ''absolute'',
''top'': $(''.side-wrapper'').offset().top + ''px'',
''bottom'': ''auto''
});
}
// if has reached the original position, return to relative positioning
if ( ($(window).scrollTop() + $(''#masthead'').height()) < originalPos ) {
$(''.side-wrapper'').css({
''position'': ''relative'',
''top'': ''auto'',
''bottom'': ''auto''
});
}
// sticky to top if scroll past top of sidebar
else if ( ($(window).scrollTop() + $(''#masthead'').height()) < $(''.side-wrapper'').offset().top && $(''.side-wrapper'').css(''position'') == ''absolute'' ) {
$(''.side-wrapper'').css({
''position'': ''fixed'',
''top'': 15 + $(''#masthead'').height() + ''px'', // padding to compensate for sticky header
''bottom'': ''auto''
});
}
}
// scroll down
else {
// unstick if scrolling the opposite direction so content will scroll with user
if ($(''.side-wrapper'').css(''position'') == ''fixed'') {
$(''.side-wrapper'').css({
''position'': ''absolute'',
''top'': $(''.side-wrapper'').offset().top + ''px'',
''bottom'': ''auto''
});
}
// check if rectbtfad (bottom most element) has reached the bottom
if ( ($(window).scrollTop() + $(window).height()) > rectbtfadPos && $(''.side-wrapper'').css(''position'') != ''fixed'' ) {
$(''.side-wrapper'').css({
''width'': $(''.col-2'').width(),
''position'': ''fixed'',
''bottom'': ''0'',
''top'': ''auto''
});
}
}
// set last scroll position to determine if scrolling up or down
lastScrollPos = $(window).scrollTop();
});
}
Algunas notas:
- .rectbtfad es el elemento más inferior en mi barra lateral
- Estoy usando la altura de mi #masthead porque es un encabezado fijo por lo que debe compensarlo
- Hay un cheque para flotador col-2 porque estoy usando un diseño receptivo y no quiero que esto se active en pantallas más pequeñas
Si alguien puede refinar esto un poco más, sería genial.
Gracias por el gran gráfico. ¡También estaba buscando una solución a este desafío!
Desafortunadamente, la otra respuesta publicada aquí no aborda el requisito n. ° 5 que estipula la capacidad de desplazarse hacia atrás a través de la barra lateral sin problemas.
Creé un violín que implementa todos los requisitos: http://jsfiddle.net/bN4qu/5/
La lógica central que debe implementarse es:
If scrolling up OR the element is shorter than viewport Then
Set top of element to top of viewport If scrolled above top of element
If scrolling down then
Set bottom of element at bottom of viewport If scrolled past bottom of element
En el violín utilizo la transformación CSS3 para mover el elemento objetivo, por lo que no funcionará, por ejemplo, IE <9. La lógica es sólida aunque para usar un enfoque diferente.
Además, modifiqué tu violín para que la barra lateral adhesiva tenga un fondo degradado. Esto ayuda a mostrar que se está exhibiendo el comportamiento adecuado.
¡Espero que esto sea útil para alguien!
Hay un complemento relativamente desconocido en el repositorio de Wordpress conocido como WP Sticky Sidebar. El complemento hace exactamente lo que usted quería (Barra lateral adhesiva: pegue al fondo cuando se desplaza hacia abajo, hacia arriba cuando se desplaza hacia arriba) WP Sticky Sidebar Repositorio de Wordpress Enlace: https://wordpress.org/plugins/mystickysidebar/
+1 a la imagen muy bonita e ilustrativa.
Sé que es una vieja pregunta, pero casualmente encontré la misma pregunta que publicaste en forum.jquery.com y una respuesta allí (por @ tucker973) , sugerí una buena biblioteca para hacer esto y quería compartirla aquí.
Se llama sticky-kit por @leafo
- proyecto github
- webpage
- ejemplo simple en jsFiddle (mismo código que el fragmento adjunto aquí)
Aquí tienes el código de un ejemplo muy básico que preparé y una demostración en funcionamiento para ver el resultado.
/*!
* Sticky-kit
* A jQuery plugin for making smart sticky elements
*
* Source: http://leafo.net/sticky-kit/
*/
$(function() {
$(".sidebar").stick_in_parent({
offset_top: 10
});
});
* {
font-size: 10px;
color: #333;
box-sizing: border-box;
}
.wrapper,
.header,
.main,
.footer {
padding: 10px;
position: relative;
}
.wrapper {
border: 1px solid #333;
background-color: #f5f5f5;
padding: 10px;
}
.header {
background-color: #6289AE;
margin-bottom: 10px;
height: 100px;
}
.sidebar {
position: absolute;
padding: 10px;
background-color: #ccc;
height: 300px;
width: 100px;
float: left;
}
.main {
background-color: #ccc;
height: 600px;
margin-left: 110px;
}
.footer {
background-color: #6289AE;
margin-top: 10px;
height: 250px;
}
.top {
position: absolute;
top: 10px;
}
.bottom {
position: absolute;
bottom: 10px;
}
.clear {
clear: both;
float: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://leafo.net/sticky-kit/src/jquery.sticky-kit.js"></script>
<div class="wrapper">
<div class="header"> <a class="top">header top</a>
<a class="bottom">header bottom</a>
</div>
<div class="content">
<div class="sidebar"> <a class="top">sidebar top</a>
<a class="bottom">sidebar bottom</a>
</div>
<div class="main"> <a class="top">main top</a>
<a class="bottom">main bottom</a>
</div>
<div class="clear"></div>
</div>
<div class="footer"> <a class="top">footer top</a>
<a class="bottom">footer bottom</a>
</div>
</div>
Por supuesto, todos los créditos van al creador del complemento, solo hice este ejemplo para mostrarlo aquí. Necesito lograr el mismo resultado que buscabas y encontré este plugin muy útil.
function fixMe(id) {
var e = $(id);
var lastScrollTop = 0;
var firstOffset = e.offset().top;
var lastA = e.offset().top;
var isFixed = false;
$(window).scroll(function(event){
if (isFixed) {
return;
}
var a = e.offset().top;
var b = e.height();
var c = $(window).height();
var d = $(window).scrollTop();
if (b <= c - a) {
e.css({position: "fixed"});
isFixed = true;
return;
}
if (d > lastScrollTop){ // scroll down
if (e.css("position") != "fixed" && c + d >= a + b) {
e.css({position: "fixed", bottom: 0, top: "auto"});
}
if (a - d >= firstOffset) {
e.css({position: "absolute", bottom: "auto", top: lastA});
}
} else { // scroll up
if (a - d >= firstOffset) {
if (e.css("position") != "fixed") {
e.css({position: "fixed", bottom: "auto", top: firstOffset});
}
} else {
if (e.css("position") != "absolute") {
e.css({position: "absolute", bottom: "auto", top: lastA});
}
}
}
lastScrollTop = d;
lastA = a;
});
}
fixMe("#stick");
Ejemplo de trabajo: https://jsfiddle.net/L7xoopst/6/