Arrêter le défilement en position fixe à un certain point?

94

J'ai un élément qui est position: fixe et donc défile avec la page comme je le veux cependant. lorsque l'utilisateur fait défiler vers le haut, je veux que l'élément arrête de défiler à un certain point, par exemple lorsqu'il est à 250 pixels du haut de la page, est-ce possible? Toute aide ou conseil serait utile merci!

J'avais le sentiment que je devrais utiliser jquery pour le faire. J'ai essayé d'obtenir le défilement ou l'emplacement de l'utilisateur, mais je suis vraiment confus, existe-t-il des solutions jquery?

Louise McComiskey
la source
1
Autant que je sache, seule une solution basée sur javascript fera ce que vous voulez. Il n'y a pas de solution CSS pure qui fasse cela.
cdeszaq

Réponses:

124

Voici un plugin jQuery rapide que je viens d'écrire et qui peut faire ce dont vous avez besoin:

$.fn.followTo = function (pos) {
    var $this = this,
        $window = $(window);

    $window.scroll(function (e) {
        if ($window.scrollTop() > pos) {
            $this.css({
                position: 'absolute',
                top: pos
            });
        } else {
            $this.css({
                position: 'fixed',
                top: 0
            });
        }
    });
};

$('#yourDiv').followTo(250);

Voir l'exemple de travail →

mVChr
la source
Cela semble prometteur oui ce que je pensais changer le positionnement à certains points, je vous ferai savoir comment je vais grâce!
Louise McComiskey
1
Salut oui merci beaucoup cela avec quelques tweeks exactement ce que je voulais et cela fonctionne maintenant parfaitement merci encore.
Louise McComiskey
3
$('window')ne devrait pas être entre guillemets. Mais merci pour cela, c'était très utile.
jeff
137

Voulez-vous dire un peu comme ça?

http://jsfiddle.net/b43hj/

$(window).scroll(function(){
    $("#theFixed").css("top", Math.max(0, 250 - $(this).scrollTop()));
});

James Montagne
la source
Super, merci beaucoup! Bien que ma tâche ait été de créer un bouton "Vers le haut" qui serait toujours au-dessus du pied de page, j'ai un peu modifié ce code. Voir ma version ici (js coffee): jsfiddle.net/9vnwx3fa/2
Alb
@James Montagne - Quelle serait la solution pour inverser ce code si je voulais l'élément fixe sticky bottom: 0; sur le défilement, puis arrêtez 250px avant d'arriver au bas de la page?
BoneStarr
1
@BoneStarr c'est un peu plus complexe. Vous devrez comparer le scrollTop actuel avec la hauteur de la page et de la fenêtre. Ensuite, vous utiliseriez simplement le même code ci-dessus, sauf avec bottomet cette valeur calculée (décalée de 250) dans le max.
James Montagne
@JamesMontagne - Avez-vous une chance de développer ce violon? J'apprécierais vraiment car je suis coincé avec celui-ci. jsfiddle.net/Hf5wH/137
BoneStarr
1
@bonestarr Considérablement plus compliqué que celui-ci. Vous devriez l'étendre à plusieurs lignes de code ou c'est vraiment difficile à comprendre. jsfiddle.net/Hf5wH/139
James Montagne
19

Voici un plugin jquery complet qui résout ce problème:

https://github.com/bigspotteddog/ScrollToFixed

La description de ce plugin est la suivante:

Ce plugin est utilisé pour fixer des éléments en haut de la page, si l'élément aurait défilé hors de la vue, verticalement; cependant, il permet à l'élément de continuer à se déplacer vers la gauche ou la droite avec le défilement horizontal.

Étant donné une option marginTop, l'élément arrêtera de se déplacer verticalement vers le haut une fois que le défilement vertical aura atteint la position cible; mais, l'élément se déplacera toujours horizontalement lorsque la page défilera vers la gauche ou la droite. Une fois que la page a fait défiler vers le bas au-delà de la position cible, l'élément sera restauré à sa position d'origine sur la page.

Ce plugin a été testé dans Firefox 3/4, Google Chrome 10/11, Safari 5 et Internet Explorer 8/9.

Utilisation pour votre cas particulier:

<script src="scripts/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="scripts/jquery-scrolltofixed-min.js" type="text/javascript"></script>

$(document).ready(function() {
    $('#mydiv').scrollToFixed({ marginTop: 250 });
});
bigspotteddog
la source
1
Merci oui cela semble vraiment utile, j'ai utilisé une réponse précédente car ce projet était il y a quelques mois, mais je garderai certainement cela à l'esprit pour les projets futurs, cela semble plus facile, merci :)
Louise McComiskey
6

Vous pouvez faire ce que James Montagne a fait avec son code dans sa réponse, mais cela le fera scintiller dans Chrome (testé en V19).

Vous pouvez corriger cela si vous mettez "margin-top" au lieu de "top". Je ne sais pas vraiment pourquoi cela fonctionne avec la marge tho.

$(window).scroll(function(){
    $("#theFixed").css("margin-top",Math.max(-250,0-$(this).scrollTop()));
});

http://jsbin.com/idacel

Jure Ravlić
la source
Cela fonctionne également très bien pour les éléments fixes sous le texte, j'ai eu un sérieux problème avec les petits écrans et mes éléments de défilement fixes remontent vers le haut du navigateur sur des zones plus petites comme 1024x768. Cela a résolu ce problème.
Joshua
2

ma solution

$(window).scroll(function(){
        if($(this).scrollTop()>425) {
            $("#theRelative").css("margin-top",$(this).scrollTop()-425);
            }   else {
                $("#theRelative").css("margin-top",$(this).scrollTop()-0);
                }
            });
            });
user3288218
la source
2

Dans un projet, j'ai en fait un en-tête fixé au bas de l'écran lors du chargement de la page (c'est une application de dessin donc l'en-tête est en bas pour donner un espace maximal à l'élément de canevas sur une large fenêtre).

J'avais besoin que l'en-tête devienne «absolu» lorsqu'il atteint le pied de page lors du défilement, car je ne veux pas que l'en-tête passe au-dessus du pied de page (la couleur de l'en-tête est la même que la couleur d'arrière-plan du pied de page).

J'ai pris la réponse la plus ancienne ici (éditée par Gearge Millo) et cet extrait de code a fonctionné pour mon cas d'utilisation. Avec un peu de jeu, je l'ai fait fonctionner. Maintenant, le titre fixe se trouve magnifiquement au-dessus du pied de page une fois qu'il atteint le pied de page.

Je pensais juste partager mon cas d'utilisation et comment cela fonctionnait, et dire merci! L'application: http://joefalconer.com/web_projects/drawingapp/index.html

    /* CSS */
    @media screen and (min-width: 1100px) {
        #heading {
            height: 80px;
            width: 100%;
            position: absolute;  /* heading is 'absolute' on page load. DOESN'T WORK if I have this on 'fixed' */
            bottom: 0;
        }
    }

    // jQuery
    // Stop the fixed heading from scrolling over the footer
    $.fn.followTo = function (pos) {
      var $this = this,
      $window = $(window);

      $window.scroll(function (e) {
        if ($window.scrollTop() > pos) {
          $this.css( { position: 'absolute', bottom: '-180px' } );
        } else {
          $this.css( { position: 'fixed', bottom: '0' } );
        }
      });
    };
    // This behaviour is only needed for wide view ports
    if ( $('#heading').css("position") === "absolute" ) {
      $('#heading').followTo(180);
    }
Joseph Falconer
la source
1

J'ai écrit un article de blog à ce sujet qui présentait cette fonction:

$.fn.myFixture = function (settings) {
  return this.each(function () {

    // default css declaration 
    var elem = $(this).css('position', 'fixed');

    var setPosition = function () {         
      var top = 0;
      // get no of pixels hidden above the the window     
      var scrollTop = $(window).scrollTop();    
      // get elements distance from top of window
      var topBuffer = ((settings.topBoundary || 0) - scrollTop);
      // update position if required
      if (topBuffer >= 0) { top += topBuffer }
      elem.css('top', top);      
    };

    $(window).bind('scroll', setPosition);
    setPosition();
  });
};
Nathan McGinness
la source
0

Une solution utilisant Mootools Framework.

http://mootools.net/docs/more/Fx/Fx.Scroll

  1. Obtenez la position (x & y) de l'élément où vous voulez arrêter le défilement en utilisant $ ('myElement'). GetPosition (). X

    $ ('myElement'). getPosition (). y

  2. Pour une sorte d'animation de défilement, utilisez:

    new Fx.Scroll ('scrollDivId', {offset: {x: 24, y: 432}}). toTop ();

  3. Pour simplement régler le défilement, utilisez immédiatement:

    new Fx.Scroll (myElement) .set (x, y);

J'espère que cela t'aides !! :RÉ

Zohaib
la source
0

J'ai aimé cette solution

$(window).scroll(function(){
    $("#theFixed").css("margin-top",Math.max(-250,0-$(this).scrollTop()));
});

mon problème était que je devais gérer un conteneur relatif à la position dans Adobe Muse.

Ma solution:

$(window).scroll(function(){
    if($(this).scrollTop()>425) {
         $("#theRelative").css("margin-top",$(this).scrollTop()-425);
    }
});
leu
la source
0

Juste du code mVChr improvisé

$(".sidebar").css('position', 'fixed')

    var windw = this;

    $.fn.followTo = function(pos) {
        var $this = this,
                $window = $(windw);

        $window.scroll(function(e) {
            if ($window.scrollTop() > pos) {
                topPos = pos + $($this).height();
                $this.css({
                    position: 'absolute',
                    top: topPos
                });
            } else {
                $this.css({
                    position: 'fixed',
                    top: 250 //set your value
                });
            }
        });
    };

    var height = $("body").height() - $("#footer").height() ;
    $('.sidebar').followTo(height);
    $('.sidebar').scrollTo($('html').offset().top);
Sreeraj
la source
La raison de stocker $(this)et $(window)dans des variables est que vous n'avez qu'à le faire $this.height()et ainsi de suite. Au lieu de définir une position supérieure, ne serait-il pas préférable que le plugin stocke la valeur supérieure d'origine et y revienne lors de la définition d'une largeur fixe? Aussi, qu'est-ce que tu veux dire Just improvised mVChr code?
Cyclonecode
0

J'ai adapté la réponse de @ mVchr et l'ai inversée pour l'utiliser pour le positionnement des publicités collantes: si vous en avez besoin absolument positionné (défilement) jusqu'à ce que l'en-tête indésirable soit hors écran, mais que vous en ayez besoin pour rester fixé / visible à l'écran après cela:

$.fn.followTo = function (pos) {
    var stickyAd = $(this),
    theWindow = $(window);
    $(window).scroll(function (e) {
      if ($(window).scrollTop() > pos) {
        stickyAd.css({'position': 'fixed','top': '0'});
      } else {
        stickyAd.css({'position': 'absolute','top': pos});
      }
    });
  };
  $('#sticky-ad').followTo(740);

CSS:

#sticky-ad {
    float: left;
    display: block;
    position: absolute;
    top: 740px;
    left: -664px;
    margin-left: 50%;
    z-index: 9999;
}
cbmtrx
la source
0

J'ai adoré la réponse @james mais je cherchais sa position inverse, c'est-à-dire arrêter la position fixe juste avant le pied de page, voici ce que j'ai trouvé

var $fixed_element = $(".some_element")
if($fixed_element.length){
        var $offset = $(".footer").position().top,
            $wh = $(window).innerHeight(),
            $diff = $offset - $wh,
            $scrolled = $(window).scrollTop();
        $fixed_element.css("bottom", Math.max(0, $scrolled-$diff));
    }

Alors maintenant, l'élément fixe s'arrêterait juste avant le pied de page. et ne se chevaucheront pas.

mshahbazm
la source