Encabezado pegajoso después de desplazarse hacia abajo


Vi este encabezado pegajoso en este sitio web: http://dunked.com/ ( ya no está activo, ver sitio archivado)

Cuando te desplazas hacia abajo, el encabezado pegajoso desciende desde la parte superior.

Miré el código, pero parece realmente complicado. Sólo entiendo esto.: El encabezado normal se clonó con JS y cuando se desplaza hacia abajo de la página se anima desde la parte superior.

Author: worldofjr, 2013-08-22

10 answers

Aquí hay un comienzo. Básicamente, copiamos el encabezado al cargar, y luego verificamos (usando .scrollTop() o window.scrollY) para ver cuando el usuario se desplaza más allá de un punto (por ejemplo, 200 píxeles). Luego simplemente alternamos una clase (en este caso .down) que mueve el original a la vista.

Por último, todo lo que necesitamos hacer es aplicar un transition: top 0.2s ease-in a nuestro clon, de modo que cuando esté en el estado .down se deslice a la vista. Dunked lo hace mejor, pero con un poco de juego es fácil configure

CSS

header {
  position: relative;
  width: 100%;
  height: 60px;
}

header.clone {
  position: fixed;
  top: -65px;
  left: 0;
  right: 0;
  z-index: 999;
  transition: 0.2s top cubic-bezier(.3,.73,.3,.74);
}

body.down header.clone {
  top: 0;
}

o bien Vanilla JS (polyfill según sea necesario)

var sticky = {
  sticky_after: 200,
  init: function() {
    this.header = document.getElementsByTagName("header")[0];
    this.clone = this.header.cloneNode(true);
    this.clone.classList.add("clone");
    this.header.insertBefore(this.clone);
    this.scroll();
    this.events();
  },

  scroll: function() {
    if(window.scrollY > this.sticky_after) {
      document.body.classList.add("down");
    }
    else {
      document.body.classList.remove("down");
    }
  },

  events: function() {
    window.addEventListener("scroll", this.scroll.bind(this));
  }
};

document.addEventListener("DOMContentLoaded", sticky.init.bind(sticky));

o jQuery

$(document).ready(function() {
  var $header = $("header"),
      $clone = $header.before($header.clone().addClass("clone"));

  $(window).on("scroll", function() {
    var fromTop = $("body").scrollTop();
    $('body').toggleClass("down", (fromTop > 200));
  });
});

Nuevas reflexiones

Mientras que lo anterior responde a la pregunta original del OP de "¿Cómo logra Dunked este efecto?", no recomendaría este enfoque. Para empezar, copiar toda la navegación superior podría ser bastante costoso, y no hay ninguna razón real por la que no podamos usar el original (con un poco de trabajo).

Además, Paul Irish y otros, han escrito sobre cómo animar con translate() es mejor que animar con top. No solo es más eficiente, sino que también significa que no necesita saber la altura exacta de su elemento. La solución anterior se modificaría con la siguiente (Ver JSFiddle):

header.clone {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  transform: translateY(-100%);
  transition: 0.2s transform cubic-bezier(.3,.73,.3,.74);
}

body.down header.clone {
  transform: translateY(0);
}

El único inconveniente con el uso de transformaciones es que, mientras que el soporte del navegador es bastante bueno, es probable que desee agregar versiones con prefijo de proveedor para maximizar la compatibilidad.

 60
Author: Ian Clark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-12 08:54:58

Aquí hay un violín JS http://jsfiddle.net/ke9kW/1 /

Como dicen los demás, establezca el encabezado en fijo e inicie con display: none

Luego jQuery

$(window).scroll(function () {
  if ( $(this).scrollTop() > 200 && !$('header').hasClass('open') ) {
    $('header').addClass('open');
    $('header').slideDown();
   } else if ( $(this).scrollTop() <= 200 ) {
    $('header').removeClass('open');
    $('header').slideUp();
  }
});

Donde 200 es la altura en píxeles a la que le gustaría que se moviera hacia abajo. La adición de la clase open es para permitirnos ejecutar un elseif en lugar de simplemente else, por lo que parte del código no se ejecuta innecesariamente en cada evento de desplazamiento, guardar un poco de memoria lil

 10
Author: joevallender,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-22 14:04:57

Aquí hay una lista de complementos de jQuery que ayudarán a lograr un efecto similar: http://jquery-plugins.net/tag/sticky-scroll

 2
Author: eagor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-21 13:18:55

Usé jQuery .función scroll() para rastrear el evento del valor de desplazamiento de la barra de herramientas usando scrollTop. Luego usé un condicional para determinar si era mayor que el valor de lo que quería reemplazar. En el siguiente ejemplo fue "Resultados". Si el valor era true, entonces la etiqueta de resultados agregó una clase 'fixedSimilarLabel' y los nuevos estilos se tuvieron en cuenta.

    $('.toolbar').scroll(function (e) {
//console.info(e.currentTarget.scrollTop);
    if (e.currentTarget.scrollTop >= 130) {
        $('.results-label').addClass('fixedSimilarLabel');
    }
    else {      
        $('.results-label').removeClass('fixedSimilarLabel');
    }
});

Http://codepen.io/franklynroth/pen/pjEzeK

 1
Author: Franklyn Roth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-25 16:12:47

Una solución similar usando jquery sería:

$(window).scroll(function () {
  $('.header').css('position','fixed');
});

Esto convierte el encabezado en un elemento de posición fija inmediatamente en scroll

 0
Author: Matt Saunders,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-22 13:59:16

Añadir debouncing, para la eficiencia http://davidwalsh.name/javascript-debounce-function

 0
Author: mrdnk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-19 21:59:25

Css:

header.sticky {
  font-size: 24px;
  line-height: 48px;
  height: 48px;
  background: #efc47D;
  text-align: left;
  padding-left: 20px;
}

JS:

$(window).scroll(function() {
 if ($(this).scrollTop() > 100){  
    $('header').addClass("sticky");
  }
  else{
    $('header').removeClass("sticky");
  }
});
 0
Author: Anup,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-02 11:20:27

Esto no estaba funcionando para mí en Firefox.

Agregamos un condicional basado en si el código coloca el desbordamiento en el nivel html. Ver Animate scrollTop no funciona en firefox.

  var $header = $("#header #menu-wrap-left"),
  $clone = $header.before($header.clone().addClass("clone"));

  $(window).on("scroll", function() {
    var fromTop = Array(); 
    fromTop["body"] = $("body").scrollTop();
    fromTop["html"] = $("body,html").scrollTop();

if (fromTop["body"]) 
    $('body').toggleClass("down", (fromTop["body"] > 650));

if (fromTop["html"]) 
    $('body,html').toggleClass("down", (fromTop["html"] > 650));

  });
 0
Author: Megan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:26

Sugiero usar sticky js es tener la mejor opción que he visto. nada que hacer solo anuncio este js en usted

 https://raw.githubusercontent.com/garand/sticky/master/jquery.sticky.js

Y utilizar el código siguiente:

<script>
  $(document).ready(function(){
    $("#sticker").sticky({topSpacing:0});
  });
</script>

Su repositorio git: https://github.com/garand/sticky

 0
Author: Shiv Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-28 10:05:17

Ventana de desplazamiento inferior a desplazamiento superior utilizando jquery.

 <script> 

 var lastScroll = 0;

 $(document).ready(function($) {

 $(window).scroll(function(){

 setTimeout(function() { 
    var scroll = $(window).scrollTop();
    if (scroll > lastScroll) {

        $("header").removeClass("menu-sticky");

    } 
    if (scroll == 0) {
    $("header").removeClass("menu-sticky");

    }
    else if (scroll < lastScroll - 5) {


        $("header").addClass("menu-sticky");

    }
    lastScroll = scroll;
    },0);
    });
   });
 </script>
 0
Author: Musaib Memdu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-12 07:19:27