Parando a rolagem de posição fixa em um determinado ponto?

94

Eu tenho um elemento que é a posição: fixo e então rola com a página como eu quero no entanto. quando o usuário rola para cima, quero que o elemento pare de rolar em um determinado ponto, digamos, quando está 250px do topo da página, isso é possível? Qualquer ajuda ou conselho seria útil, obrigado!

Tive a sensação de que precisaria usar jquery para fazer isso. Eu tentei obter a rolagem ou localização de onde o usuário está, mas fiquei muito confuso, há alguma solução jquery?

Louise McComiskey
fonte
1
Pelo que eu sei, apenas uma solução baseada em javascript fará o que você quiser. Não existe uma solução CSS pura que faça isso.
cdeszaq

Respostas:

124

Aqui está um plug-in jQuery rápido que acabei de escrever que pode fazer o que você precisa:

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

Veja o exemplo de trabalho →

mVChr
fonte
Isso parece promissor sim, o que eu pensei em mudar o posicionamento em certos pontos, vou te dizer como eu fico, obrigado!
Louise McComiskey
1
Olá, sim, muito obrigado com alguns ajustes para exatamente o que eu queria e agora está funcionando perfeitamente, obrigado novamente.
Louise McComiskey
3
$('window')não deve estar entre aspas. Mas obrigado por isso, foi muito útil.
jeff
137

Você quer dizer mais ou menos assim?

http://jsfiddle.net/b43hj/

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

James Montagne
fonte
Ótimo, muito obrigado! Embora minha tarefa fosse criar o botão "Para o topo" que estaria sempre acima do rodapé, modifiquei um pouco esse código. Veja minha versão aqui (café js): jsfiddle.net/9vnwx3fa/2
Alb
@James Montagne - Qual seria a solução para reverter esse código se eu quisesse o elemento fixo sticky bottom: 0; ao rolar e parar 250px antes de chegar ao final da página?
BoneStarr
1
@BoneStarr é um pouco mais complexo. Você precisaria comparar o scrollTop atual com a altura da página e a janela de visualização. Então, você simplesmente usaria o mesmo código acima, exceto com bottome este valor calculado (deslocamento de 250) no máx.
James Montagne
@JamesMontagne - Alguma chance de você elaborar esse violino? Eu realmente aprecio isso, pois estou preso com este. jsfiddle.net/Hf5wH/137
BoneStarr
1
@bonestarr Consideravelmente mais complicado do que este. Você deve expandi-lo para várias linhas de código ou é realmente difícil de entender. jsfiddle.net/Hf5wH/139
James Montagne
19

Aqui está um plugin jquery completo que resolve este problema:

https://github.com/bigspotteddog/ScrollToFixed

A descrição deste plugin é a seguinte:

Este plugin é usado para fixar elementos no topo da página, se o elemento tivesse rolado para fora da visualização, verticalmente; no entanto, permite que o elemento continue a se mover para a esquerda ou direita com a rolagem horizontal.

Dada uma opção marginTop, o elemento irá parar de se mover verticalmente para cima assim que a rolagem vertical atingir a posição de destino; mas, o elemento ainda se moverá horizontalmente conforme a página é rolada para a esquerda ou direita. Uma vez que a página foi rolada de volta para baixo após a posição de destino, o elemento será restaurado à sua posição original na página.

Este plug-in foi testado no Firefox 3/4, Google Chrome 10/11, Safari 5 e Internet Explorer 8/9.

Uso para seu caso particular:

<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
fonte
1
Obrigado, sim, parece muito útil, usei uma resposta anterior, pois este projeto foi há alguns meses, no entanto, com certeza vou manter isso em mente para projetos futuros, parece mais fácil, obrigado :)
Louise McComiskey
6

Você pode fazer o que James Montagne fez com seu código em sua resposta, mas isso o fará piscar no Chrome (testado em V19).

Você pode consertar isso se colocar "margin-top" em vez de "top". Realmente não sei por que funciona com o margin tho.

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

http://jsbin.com/idacel

Jure Ravlić
fonte
Isso funciona muito bem para elementos fixos abaixo do texto também. Tenho tido um sério problema com telas pequenas e meus elementos de rolagem fixos chegam ao topo do navegador em áreas menores, como 1024x768. Isso resolveu o problema.
Joshua
2

minha solução

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

Em um projeto, na verdade, tenho algum título fixado na parte inferior da tela no carregamento da página (é um aplicativo de desenho, portanto, o título fica na parte inferior para dar espaço máximo para o elemento de tela na janela de visualização ampla).

Eu precisava que o título se tornasse 'absoluto' quando atingir o rodapé na rolagem, já que não quero o título acima do rodapé (a cor do título é igual à cor de fundo do rodapé).

Peguei a resposta mais antiga aqui (editada por Gearge Millo) e aquele trecho de código funcionou para meu caso de uso. Com algumas brincadeiras, consegui fazer isso funcionar. Agora, o título fixo fica lindamente acima do rodapé quando atinge o rodapé.

Pensei em compartilhar meu caso de uso e como ele funcionava, e dizer obrigado! O aplicativo: 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
fonte
1

Escrevi uma postagem no blog sobre isso que apresentava esta função:

$.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
fonte
0

Uma solução usando Mootools Framework.

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

  1. Obtenha a posição (x e y) do elemento em que deseja parar a rolagem usando $ ('myElement'). GetPosition (). X

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

  2. Para um tipo de rolagem de animação, use:

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

  3. Para definir a rolagem imediatamente, use:

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

Espero que isto ajude !! : D

Zohaib
fonte
0

Gostei desta solução

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

meu problema era que eu tinha que lidar com um contêiner relativo de posição no Adobe Muse.

Minha solução:

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

Código mVChr apenas improvisado

$(".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
fonte
A razão para armazenar $(this)e $(window)em variáveis ​​é que você só precisa fazer $this.height()e assim por diante. Em vez de definir uma posição superior, não seria melhor se o plugin armazenasse o valor superior original e revertesse para ele ao definir uma largura fixa? Além disso, o que você quer dizer com Just improvised mVChr code?
Cyclonecode
0

Eu adaptei a resposta de @mVchr e a inverti para usar no posicionamento de anúncio fixo: se você precisar posicioná-lo absolutamente (rolando) até que o lixo do cabeçalho esteja fora da tela, mas depois precisa que ele permaneça fixo / visível na tela:

$.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
fonte
0

Adorei a resposta do @james, mas estava procurando o inverso, ou seja, pare a posição fixa antes do rodapé, aqui está o que eu descobri

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

Portanto, agora o elemento fixo iria parar antes do rodapé. e não se sobreporá a ele.

mshahbazm
fonte