En-tête collante après défilement

j'ai vu cet en-tête collant sur ce site: http://dunked.com/ (n'est plus actif, voir le site archivé )

quand vous faites défiler l'en-tête collant descend du haut.

j'ai regardé le code, mais il semble vraiment compliqué. Je ne comprends que ce: L'en-tête normal a été cloné avec JS et quand vous faites défiler la page elle s'anime depuis le haut.

26
demandé sur worldofjr 2013-08-22 17:54:25

10 réponses

voici un début . Fondamentalement, nous copions l'en-tête au chargement, puis vérifions (en utilisant .scrollTop() ou window.scrollY ) pour voir quand l'utilisateur défile au-delà d'un point (par exemple 200pixels). Ensuite nous basculons simplement une classe (dans ce cas .down ) qui déplace l'original en vue.

enfin tout ce que nous avons à faire est d'appliquer un transition: top 0.2s ease-in à notre clone, de sorte que quand il est dans l'état .down il glisse dans la vue. Dunked le fait mieux, mais avec un peu de jeu autour il est facile de configurer

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;
}

soit Vanilla js (polyfill as required)

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));

ou 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));
  });
});

Nouvelles Réflexions

alors que ce qui précède répond à la question originale de L'OP "comment Dunked obtenir cet effet?" , Je ne recommande pas cette approche. Pour commencer, copier toute la navigation du haut pourrait être assez coûteux, et il n'y a pas de vraie raison pour que nous ne puissions pas utiliser l'original (avec un peu de travail).

en outre, Paul Irish et d'autres, ont écrit sur comment animer avec translate() est mieux que l'animation avec top . Non seulement est-il plus performant, mais cela signifie également que vous n'avez pas besoin de connaître la taille exacte de votre élément. La solution ci-dessus serait modifiée comme suit: (voir 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);
}

le seul inconvénient avec l'utilisation de transformées est que, tandis que le soutien de navigateur est assez bon , vous voudrez probablement ajouter des versions préfixées de vendeur pour maximiser la compatibilité.

60
répondu Ian Clark 2015-02-12 08:54:58

voici un violon JS http://jsfiddle.net/ke9kW/1 /

comme disent les autres, réglez l'en-tête sur fixe, et démarrez avec display: none

puis 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();
  }
});

où 200 est la hauteur en pixels que vous souhaitez qu'il descende. L'ajout de la classe open est pour nous permettre d'exécuter un elseif au lieu d'un simple ElseIf, de sorte qu'une partie du code ne s'exécute pas inutilement sur chaque scrollevent, petit morceau de mémoire

10
répondu joevallender 2013-08-22 14:04:57

voici toute une liste de jQuery plugins qui aideront à obtenir un effet similaire: http://jquery-plugins.net/tag/sticky-scroll

2
répondu eagor 2014-08-21 13:18:55

j'ai utilisé jQuery .fonction de défilement() pour suivre l'événement de la valeur de défilement de la barre d'outils en utilisant scrollTop. J'ai ensuite utilisé un conditionnel pour déterminer s'il était supérieur à la valeur de ce que je voulais remplacer. Dans l'exemple ci-dessous, il était "Résultats". Si la valeur était vraie, alors les résultats-étiquette a ajouté une classe "fixedSimilarLabel" et les nouveaux styles ont ensuite été pris en compte.

    $('.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
répondu Franklyn Roth 2015-09-25 16:12:47

une solution similaire utilisant jquery serait:

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

cela transforme l'en-tête en un élément de position fixe immédiatement sur le rouleau

0
répondu Matt Saunders 2013-08-22 13:59:16

Ajouter de l'anti-rebond, pour plus d'efficacité http://davidwalsh.name/javascript-debounce-function

0
répondu mrdnk 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
répondu Anup 2016-03-02 11:20:27

cela ne marchait pas pour moi dans Firefox.

nous avons ajouté une condition basée sur le fait que le code place le débordement au niveau html. Voir scrollTop Animé ne travaillant pas dans 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
répondu Megan 2017-05-23 12:26:26

je suggère d'utiliser sticky js c'est la meilleure option que j'ai jamais vu. rien à faire, juste à cette annonce js sur vous

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

et utiliser le code ci-dessous :

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

Son repo git: https://github.com/garand/sticky

0
répondu Shiv Singh 2017-03-28 10:05:17

bas de la fenêtre de défilement vers le haut défilement à l'aide de 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
répondu Musaib Memdu 2017-07-12 07:19:27