Zatrzymywanie przewijania ustalonej pozycji w pewnym momencie?

96

Mam element, który jest ustawiony na stałe, więc przewija się ze stroną tak, jak chcę. kiedy użytkownik przewija w górę, chcę, aby element przestał się przewijać w pewnym momencie, powiedzmy, gdy znajduje się 250 pikseli od góry strony, czy jest to możliwe? Każda pomoc lub rada byłaby pomocna, dzięki!

Wydawało mi się, że do tego celu będę musiał użyć jquery. Próbowałem uzyskać przewijanie lub lokalizację miejsca, w którym znajduje się użytkownik, ale byłem naprawdę zdezorientowany, czy są jakieś rozwiązania jQuery?

Louise McComiskey
źródło
1
O ile wiem, tylko rozwiązanie oparte na javascript zrobi to, co chcesz. Nie ma czystego rozwiązania CSS, które to robi.
cdeszaq

Odpowiedzi:

124

Oto krótka wtyczka jQuery, którą właśnie napisałem, która może zrobić to, czego potrzebujesz:

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

Zobacz przykład roboczy →

mVChr
źródło
To wygląda obiecująco, tak, to co myślałem, zmieniając pozycjonowanie w niektórych punktach, dam ci znać, jak sobie radzę, dzięki!
Louise McComiskey
1
Cześć, tak, dziękuję bardzo z kilkoma tweeksami do dokładnie tego, czego chciałem, a teraz działa doskonale, dzięki ponownie.
Louise McComiskey
3
$('window')nie powinno być w cudzysłowie. Ale dzięki za to, było to bardzo pomocne.
jeff
138

Masz na myśli coś takiego?

http://jsfiddle.net/b43hj/

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

James Montagne
źródło
Dziękuję bardzo! Chociaż moim zadaniem było stworzenie przycisku „Na górę”, który będzie zawsze nad stopką, zmodyfikowałem nieco ten kod. Zobacz moją wersję tutaj (js coffee): jsfiddle.net/9vnwx3fa/2
Alb
@James Montagne - Jakie byłoby rozwiązanie odwrócenia tego kodu, gdybym chciał, aby element stały sticky bottom: 0; na przewijaniu, a następnie zatrzymanie 250px, zanim dotrze na dół strony?
BoneStarr
1
@BoneStarr to trochę bardziej złożone. Musisz porównać bieżące scrollTop z wysokością strony i widocznym obszarem. Następnie wystarczy użyć tego samego kodu powyżej, z wyjątkiem opcji bottomi tej obliczonej wartości (przesunięcie o 250) w maks.
James Montagne
@JamesMontagne - Czy masz szansę rozwinąć te skrzypce? Naprawdę by to docenił, ponieważ utknąłem z tym. jsfiddle.net/Hf5wH/137
BoneStarr
1
@bonestarr Znacznie bardziej skomplikowane niż to. Powinieneś rozszerzyć go na wiele wierszy kodu lub jest to naprawdę trudne do zrozumienia. jsfiddle.net/Hf5wH/139
James Montagne
19

Oto kompletna wtyczka jquery, która rozwiązuje ten problem:

https://github.com/bigspotteddog/ScrollToFixed

Opis tej wtyczki jest następujący:

Ta wtyczka służy do mocowania elementów na górze strony, jeśli element zostałby przewinięty poza widok, pionowo; jednak pozwala elementowi na dalsze przesuwanie w lewo lub w prawo za pomocą poziomego przewijania.

Mając opcję marginTop, element przestanie przesuwać się pionowo w górę, gdy przewijanie w pionie osiągnie pozycję docelową; ale element będzie nadal przesuwał się w poziomie podczas przewijania strony w lewo lub w prawo. Po przewinięciu strony z powrotem w dół poza położenie docelowe, element zostanie przywrócony do pierwotnej pozycji na stronie.

Ta wtyczka została przetestowana w przeglądarkach Firefox 3/4, Google Chrome 10/11, Safari 5 i Internet Explorer 8/9.

Użycie w konkretnym przypadku:

<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
źródło
1
Dziękuję tak, wygląda to na naprawdę przydatne, użyłem poprzedniej odpowiedzi, ponieważ ten projekt był kilka miesięcy temu, ale na pewno będę o tym pamiętać w przyszłych projektach, wygląda to łatwiej, dzięki :)
Louise McComiskey
6

Możesz zrobić to, co James Montagne zrobił ze swoim kodem w swojej odpowiedzi, ale spowoduje to migotanie w Chrome (testowane w V19).

Możesz to naprawić, wstawiając „margin-top” zamiast „top”. Naprawdę nie wiem, dlaczego to działa z marginesem.

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

http://jsbin.com/idacel

Jure Ravlić
źródło
Działa to również świetnie w przypadku stałych elementów pod tekstem. Miałem poważny problem z małymi ekranami, a moje stałe elementy przewijania biegły do ​​góry przeglądarki na mniejszych obszarach, takich jak 1024x768. To rozwiązało ten problem.
Joshua,
2

moje rozwiązanie

$(window).scroll(function(){
        if($(this).scrollTop()>425) {
            $("#theRelative").css("margin-top",$(this).scrollTop()-425);
            }   else {
                $("#theRelative").css("margin-top",$(this).scrollTop()-0);
                }
            });
            });
user3288218
źródło
2

W projekcie faktycznie mam jakiś nagłówek przymocowany do dołu ekranu podczas wczytywania strony (jest to aplikacja do rysowania, więc nagłówek znajduje się na dole, aby zapewnić maksymalne miejsce na element Canvas w szerokim oknie roboczym).

Potrzebowałem, aby nagłówek stał się „absolutny”, gdy dotrze do stopki na przewijaniu, ponieważ nie chcę, aby nagłówek znajdował się nad stopką (kolor nagłówka jest taki sam jak kolor tła stopki).

Wziąłem tutaj najstarszą odpowiedź (edytowaną przez Gearge Millo) i ten fragment kodu działał w moim przypadku użycia. Po zabawie udało mi się to. Teraz ustalony nagłówek pięknie leży nad stopką, gdy dotrze do stopki.

Pomyślałem, że podzielę się moim przykładem użycia i tym, jak to działa, i podziękuję! Aplikacja: 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
źródło
1

Napisałem o tym post na blogu, który zawierał tę funkcję:

$.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
źródło
0

Rozwiązanie wykorzystujące Mootools Framework.

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

  1. Uzyskaj pozycję (x i y) elementu, w którym chcesz zatrzymać przewijanie za pomocą $ ('myElement'). GetPosition (). X

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

  2. Do animacji użyj:

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

  3. Aby natychmiast ustawić przewijanie, użyj:

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

Mam nadzieję że to pomoże !! :RE

Zohaib
źródło
0

Podobało mi się to rozwiązanie

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

mój problem polegał na tym, że miałem do czynienia z kontenerem względnym położenia w Adobe Muse.

Moje rozwiązanie:

$(window).scroll(function(){
    if($(this).scrollTop()>425) {
         $("#theRelative").css("margin-top",$(this).scrollTop()-425);
    }
});
leja
źródło
0

Po prostu improwizowany kod mVChr

$(".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
źródło
Powodem przechowywania $(this)i $(window)w zmiennych jest to, że musisz tylko zrobić $this.height()i tak dalej. Zamiast ustawiać najwyższą pozycję, czy nie byłoby lepiej, gdyby wtyczka zapisała pierwotną górną wartość i przywróciła ją podczas ustawiania stałej szerokości? Co masz na myśli Just improvised mVChr code?
Cyclonecode
0

Dostosowałem odpowiedź @ mVchr i odwróciłem ją, aby użyć do pozycjonowania reklamy przyklejonej: jeśli potrzebujesz jej absolutnie pozycjonowanej (przewijanie), aż śmieci nagłówka znikną z ekranu, ale potem chcesz, aby pozostała naprawiona / widoczna na ekranie:

$.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
źródło
0

Uwielbiałem odpowiedź @james, ale szukałem jej odwrotności, tj. Zatrzymaj stałą pozycję tuż przed stopką, oto co wymyśliłem

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

Więc teraz stały element zatrzymałby się tuż przed stopką. i nie będzie się z nim pokrywać.

mshahbazm
źródło