Jak sprawić, by div przykleił się do górnej części ekranu po przewinięciu?


305

Chciałbym utworzyć div, który znajduje się pod blokiem treści, ale który po przewinięciu strony na tyle, by zetknąć się z górną granicą, zostaje ustalony i przewija się wraz ze stroną.


5
Od czerwca 2014 r. Wtyczka jQuery Sticky-kit jest jedną z najłatwiejszych opcji, zapewniając wyjątkowo niską barierę wejścia i wiele funkcji. Świetne miejsce na początek, jeśli szukasz łatwego sposobu szybkiego zejścia z ziemi.
user456584


32
Dodanie CSS position: sticky; top:0;działa w większości przeglądarek w styczniu 2017 r.
Colin 't Hart

9
Cholera jasna, ta position: sticky;rzecz jest magiczna.
tscizzle

Odpowiedzi:


259

Możesz użyć po prostu css, ustawiając swój element jako stały :

.fixedElement {
    background-color: #c0c0c0;
    position:fixed;
    top:0;
    width:100%;
    z-index:100;
}

Edycja: Powinieneś mieć element z pozycją bezwzględną, gdy przesunięcie przewijania osiągnie element, należy go zmienić na stały, a górną pozycję należy ustawić na zero.

Możesz wykryć przesunięcie górnego przewijania dokumentu za pomocą funkcji scrollTop :

$(window).scroll(function(e){ 
  var $el = $('.fixedElement'); 
  var isPositionFixed = ($el.css('position') == 'fixed');
  if ($(this).scrollTop() > 200 && !isPositionFixed){ 
    $el.css({'position': 'fixed', 'top': '0px'}); 
  }
  if ($(this).scrollTop() < 200 && isPositionFixed){
    $el.css({'position': 'static', 'top': '0px'}); 
  } 
});

Kiedy przesunięcie przewijania osiągnie 200, element przyklei się do górnej części okna przeglądarki, ponieważ zostanie ustawiony jako stały.


4
to nie osiąga tego, co zamierzam. Chciałbym, aby element zaczynał się od 200 pikseli poniżej góry strony (aby umożliwić miejsce na inne treści), a następnie, gdy użytkownik przewinie w dół, zostanie ustalony na górze.
evanr

3
Twoja edycja rzeczywiście spełnia potrzeby pytania teraz, ale nadal masz problem, gdy strona przewija się ponownie na górę. możesz po osiągnięciu elementu scrollTop zapisać go gdzieś, a kiedy strona ponownie trafi w tę pozycję (podczas przewijania w górę), zmień css z powrotem na domyślny ... prawdopodobnie lepiej to zrobić za pomocą .toggleClass, a następnie ...
Sander

9
Jest to w zasadzie co, kiedy, ale musiałem usunąć stałe pozycjonowanie, gdy okno jest przewijane z powrotem na górę. if ($(this).scrollTop() < 200 && $el.css('position') == 'fixed') { $('.fixedElement').css({'position': 'static', 'top': '0px'}); }
Derrick Petzold

1
@DerrickPetzold Włożyłem to do odpowiedzi, bardzo ważne rzeczy :)
MarioDS

1
new exampleLink dałeś tyle czyste i jasne, że nie mogę nawet zobaczyć! -_-
sohaiby

245

Widziałeś ten przykład na stronie problemu Google Code i (dopiero niedawno) na stronie edycji Przepełnienie stosu.

Odpowiedź CMS nie zmienia pozycji podczas przewijania w górę. Oto bezwstydnie skradziony kod z przepełnienia stosu:

function moveScroller() {
    var $anchor = $("#scroller-anchor");
    var $scroller = $('#scroller');

    var move = function() {
        var st = $(window).scrollTop();
        var ot = $anchor.offset().top;
        if(st > ot) {
            $scroller.css({
                position: "fixed",
                top: "0px"
            });
        } else {
            $scroller.css({
                position: "relative",
                top: ""
            });
        }
    };
    $(window).scroll(move);
    move();
}
<div id="sidebar" style="width:270px;"> 
  <div id="scroller-anchor"></div> 
  <div id="scroller" style="margin-top:10px; width:270px"> 
    Scroller Scroller Scroller
  </div>
</div>

<script type="text/javascript"> 
  $(function() {
    moveScroller();
  });
</script> 

I proste demo na żywo .

Powstająca alternatywa bez skryptów position: stickyjest obsługiwana w Chrome, Firefox i Safari. Zobacz artykuł na temat HTML5Rocks i wersji demo oraz dokumentów Mozilli .


3
Z jakiegoś powodu {scroll: false} dawał mi problemy (jQuery 1.6.2). Wydaje się, że działa bez niego. Widelec z połączonej wersji demo. Masz pomysł, jeśli służy to celowi?
Eddie,

Mam z tym wiele kłopotów, nie mogę powielać mojego życia, próbowałem nawet odtworzyć demo na żywo i nie działa. czy ktoś może link do samouczka, który zawiera instrukcje krok po kroku?
Trevor Dupp,

2
Wydaje się, że działa to dobrze, gdy używam tej samej wersji jQuery co demo (1.3.2). W pewnym momencie offsetmusiał przestać akceptować obiekt jako dane wejściowe api.jquery.com/offset . @Eddie Twoja modyfikacja powinna być bezpieczna z obecnym jQuery.
Graeme,

1
Czy jest jakiś powód, dla którego nie może zastąpić var d = $("#scroller-anchor").offset().top;z var d = $("#sidebar").offset().top;i pozbyć się pustych-scroller kotwicy div wszystko razem? Oto mój widelec pokazujący, o czym mówię.
Mike Deck

@MikeDeck Podejrzewam, że jeśli istnieją marginesy lub wypełnienia, chciałbyś mieć możliwość kontrolowania położenia przewijania względem kontenera.
Josh Lee

72

Od stycznia 2017 r. I wydania Chrome 56 większość powszechnie używanych przeglądarek obsługuje tę position: stickywłaściwość w CSS.

#thing_to_stick {
  position: sticky;
  top: 0px;
}

robi to dla mnie w Firefoxie i Chrome.

W Safari nadal musisz korzystać position: -webkit-sticky.

Wielokrotne wypełnianie jest dostępne dla Internet Explorera i Edge; https://github.com/wilddeer/stickyfill wydaje się być dobrym rozwiązaniem.


5
Jest to obsługiwane w większości powszechnie używanych obecnie przeglądarek. Zobacz caniuse.com/#feat=css-sticky Po drugie, zdecydowanie wolę rozwiązanie, które można sprowadzić do 2 linii kodu, niż wersja wymagająca niestandardowego Javascript. I jest również przyszłościowy. Użyj polifillu, jeśli martwisz się kompatybilnością przeglądarki.
Colin 't Hart

1
Nie może być łatwiejsze niż to :)
rozpoczęło się

1
Chciałbym dodać do tego komentarza, że ​​możemy z-index: 99999 ;, ponieważ jeśli nie, gdy dojdzie do góry, druga treść zostanie wyświetlona jako pierwsza. Ale to powinno być przyjęte rozwiązanie.
dayanrr91

Po prostu zawiń go w div z id = "thing_to_stick"
Anton

Proste i łatwe rozwiązanie. I oczywiście działa lepiej niż inne rozwiązania.
fsevenm

33

Miałem ten sam problem co ty i skończyłem z tworzeniem wtyczki jQuery, aby się tym zająć. W rzeczywistości rozwiązuje wszystkie problemy, które wymienili tutaj ludzie, a także dodaje kilka opcjonalnych funkcji.

Opcje

stickyPanelSettings = {
    // Use this to set the top margin of the detached panel.
    topPadding: 0,

    // This class is applied when the panel detaches.
    afterDetachCSSClass: "",

    // When set to true the space where the panel was is kept open.
    savePanelSpace: false,

    // Event fires when panel is detached
    // function(detachedPanel, panelSpacer){....}
    onDetached: null,

    // Event fires when panel is reattached
    // function(detachedPanel){....}
    onReAttached: null,

    // Set this using any valid jquery selector to 
    // set the parent of the sticky panel.
    // If set to null then the window object will be used.
    parentSelector: null
};

https://github.com/donnyv/sticky-panel

demo: http://htmlpreview.github.io/?https://github.com/donnyv/sticky-panel/blob/master/jquery.stickyPanel/Main.htm


1
Hej! Dziękuję Ci! To świetne rozwiązanie i dzięki za dzielenie się, na pewno zaoszczędziło mi to dużo czasu. To powinno być ogólnie przyjęte rozwiązanie tego pytania, ponieważ o ile przeczytałem, jest to najbardziej kompletne rozwiązanie. Zasadniczo inne nie rozwiązały problemu z oryginalną pozycją X bloku po pozycji: stosowany jest styl stały. Twój rozwiązuje ten problem. Naprawdę wielkie dzięki!
Marcos Buarque

Hej Donny, uwielbiam też twoją wtyczkę (v1.4.1) ... natknąłem się na jeden problem, elementy blokowe straciły swoją szerokość, jeśli nie określono żadnego. Więc zmieniłem to podczas odłączania ... tylko przez ustawienie szerokości, aby pozostała taka sama. code// zdejmij panel node.css ({"margin": 0, "left": nodeLeft, "top": newNodeTop, "position": "fixed", "width": node.width ()}); code
Will Hancock

Szukałem i wypróbowałem wiele rozwiązań, a to zadziałało „od razu po wyjęciu z pudełka”. Znakomita robota! Dziękuję Ci!
ajtatum

2
@WillHancock Dodałem obsługę iPada, naprawiłem błąd odświeżania i dodałem zdarzenia OnDetached i onReattached. Nowe wydarzenia umożliwią dostęp do panelu i panelu rozdzielającego po jego odłączeniu i ponownym podłączeniu.
Donny V.

4
Dodano także opcję ParentSelector do obsługi przewijanych div.
Donny V.

24

A oto jak bez jquery (AKTUALIZACJA: zobacz inne odpowiedzi, w których możesz to teraz zrobić tylko za pomocą CSS)

var startProductBarPos=-1;
window.onscroll=function(){
  var bar = document.getElementById('nav');
  if(startProductBarPos<0)startProductBarPos=findPosY(bar);

  if(pageYOffset>startProductBarPos){
    bar.style.position='fixed';
    bar.style.top=0;
  }else{
    bar.style.position='relative';
  }

};

function findPosY(obj) {
  var curtop = 0;
  if (typeof (obj.offsetParent) != 'undefined' && obj.offsetParent) {
    while (obj.offsetParent) {
      curtop += obj.offsetTop;
      obj = obj.offsetParent;
    }
    curtop += obj.offsetTop;
  }
  else if (obj.y)
    curtop += obj.y;
  return curtop;
}
* {margin:0;padding:0;}
.nav {
  border: 1px red dashed;
  background: #00ffff;
  text-align:center;
  padding: 21px 0;

  margin: 0 auto;
  z-index:10; 
  width:100%;
  left:0;
  right:0;
}

.header {
  text-align:center;
  padding: 65px 0;
  border: 1px red dashed;
}

.content {
  padding: 500px 0;
  text-align:center;
  border: 1px red dashed;
}
.footer {
  padding: 100px 0;
  text-align:center;
  background: #777;
  border: 1px red dashed;
}
<header class="header">This is a Header</header>
<div id="nav" class="nav">Main Navigation</div>
<div class="content">Hello World!</div>
<footer class="footer">This is a Footer</footer>


4
Dziękuję Ci! W dzisiejszych czasach coraz trudniej znaleźć natywne rozwiązania JS. To działało idealnie.
Sherri

Dziękuję bardzo, działało to doskonale, ponieważ jquery kolidowało z jakimś starszym kodem korporacyjnym, który mój projekt ma
sng

chociaż mam problem z tym, że jeśli przewinę na dół strony, automatycznie wyskoczy z powrotem na górę.
śng

@sng Czy moja przykładowa strona to robi?
Jim W mówi o przywróceniu Moniki

@JimW Znalazłem problem. Próbowałem go użyć z pionowym paskiem menu obok głównego div treści po lewej stronie. Występował błąd podczas przewijania w dół, ponieważ nie można ustalić, kiedy prawidłowo trafia na dół strony. Skończyło się na dodaniu wiersza kodu, aby ustawić wysokość div kontenera do rozmiaru ekranu okna do detektora zdarzeń przewijania
sng

9

Tak to zrobiłem z jquery. Wszystko to zostało zebrane razem z różnych odpowiedzi na temat przepełnienia stosu. To rozwiązanie buforuje selektory w celu szybszego działania, a także rozwiązuje problem „skakania”, gdy lepki div staje się lepki.

Sprawdź to na jsfiddle: http://jsfiddle.net/HQS8s/

CSS:

.stick {
    position: fixed;
    top: 0;
}

JS:

$(document).ready(function() {
    // Cache selectors for faster performance.
    var $window = $(window),
        $mainMenuBar = $('#mainMenuBar'),
        $mainMenuBarAnchor = $('#mainMenuBarAnchor');

    // Run this on scroll events.
    $window.scroll(function() {
        var window_top = $window.scrollTop();
        var div_top = $mainMenuBarAnchor.offset().top;
        if (window_top > div_top) {
            // Make the div sticky.
            $mainMenuBar.addClass('stick');
            $mainMenuBarAnchor.height($mainMenuBar.height());
        }
        else {
            // Unstick the div.
            $mainMenuBar.removeClass('stick');
            $mainMenuBarAnchor.height(0);
        }
    });
});

7

Oto kolejna opcja:

JAVASCRIPT

var initTopPosition= $('#myElementToStick').offset().top;   
$(window).scroll(function(){
    if($(window).scrollTop() > initTopPosition)
        $('#myElementToStick').css({'position':'fixed','top':'0px'});
    else
        $('#myElementToStick').css({'position':'absolute','top':initTopPosition+'px'});
});

Twój #myElementToStickpowinien zacząć position:absolutewłasności CSS.


1
Myślę, że to bardzo czyste i łatwe rozwiązanie. Po prostu nie ustawiłbym elementu jako „absolutny” - może to zepsuć układ - po prostu ustawiłem go na statyczny.
Gerfried

4

Jak powiedzieli Josh Lee i Colin 't Hart , możesz opcjonalnie po prostu użyćposition: sticky; top: 0; zastosowanie do div, którego chcesz przewijać w ...

Ponadto jedyne, co musisz zrobić, to skopiować to na górę strony lub sformatować, aby zmieściło się w zewnętrznym arkuszu CSS:

<style>
#sticky_div's_name_here { position: sticky; top: 0; }
</style>

Po prostu zamień #sticky_div's_name_herena nazwę swojej div, tzn. Jeśli div <div id="example">byłby, wstawisz #example { position: sticky; top: 0; }.


1

Moje rozwiązanie jest trochę pełne, ale obsługuje zmienne pozycjonowanie od lewej krawędzi dla wyśrodkowanych układów.

// Ensurs that a element (usually a div) stays on the screen
//   aElementToStick   = The jQuery selector for the element to keep visible
global.makeSticky = function (aElementToStick) {
    var $elementToStick = $(aElementToStick);
    var top = $elementToStick.offset().top;
    var origPosition = $elementToStick.css('position');

    function positionFloater(a$Win) {
        // Set the original position to allow the browser to adjust the horizontal position
        $elementToStick.css('position', origPosition);

        // Test how far down the page is scrolled
        var scrollTop = a$Win.scrollTop();
        // If the page is scrolled passed the top of the element make it stick to the top of the screen
        if (top < scrollTop) {
            // Get the horizontal position
            var left = $elementToStick.offset().left;
            // Set the positioning as fixed to hold it's position
            $elementToStick.css('position', 'fixed');
            // Reuse the horizontal positioning
            $elementToStick.css('left', left);
            // Hold the element at the top of the screen
            $elementToStick.css('top', 0);
        }
    }

    // Perform initial positioning
    positionFloater($(window));

    // Reposition when the window resizes
    $(window).resize(function (e) {
        positionFloater($(this));
    });

    // Reposition when the window scrolls
    $(window).scroll(function (e) {
        positionFloater($(this));
    });
};

1

Oto jeszcze jedna wersja do wypróbowania dla tych, którzy mają problemy z innymi. Łączy w sobie techniki omówione w tym zduplikowanym pytaniu i generuje wymagane DIV pomocnicze dynamicznie, więc nie jest wymagany dodatkowy HTML.

CSS:

.sticky { position:fixed; top:0; }

JQuery:

function make_sticky(id) {
    var e = $(id);
    var w = $(window);
    $('<div/>').insertBefore(id);
    $('<div/>').hide().css('height',e.outerHeight()).insertAfter(id);
    var n = e.next();
    var p = e.prev();
    function sticky_relocate() {
      var window_top = w.scrollTop();
      var div_top = p.offset().top;
      if (window_top > div_top) {
        e.addClass('sticky');
        n.show();
      } else {
        e.removeClass('sticky');
        n.hide();
      }
    }
    w.scroll(sticky_relocate);
    sticky_relocate();
}

Aby element był lepki, wykonaj:

make_sticky('#sticky-elem-id');

Kiedy element staje się lepki, kod zarządza pozycją pozostałej zawartości, aby zapobiec przeskakiwaniu do szczeliny pozostawionej przez lepki element. Przywraca również element lepki do jego pierwotnej niekleistej pozycji podczas przewijania powyżej niego.


Twoje podejście jest bardzo podobne do podejścia JohnB . Biorąc pod uwagę różnice w stosunku do tej odpowiedzi, zastanawiam się (1) Czy jest korzyść z używania drugiego „pomocnika div” (zamiast tylko 1, jak JohnB używa), oraz (2) Czy istnieje korzyść z użycia hide () i show () zamiast ustawiania wysokości div pomocnika (tak jak robi to JohnB)? Być może różnica w wydajności? Do tej pory nie byłem w stanie dostrzec różnic, ale być może niektóre scenariusze miałyby różnice (na przykład z udziałem elementów wbudowanych lub czegoś takiego), dlatego pytam. Dzięki.
Jason Frank

1

Oto rozszerzona wersja odpowiedzi Josha Lee. Jeśli chcesz, aby div znajdował się na pasku bocznym po prawej stronie i unosił się w zakresie (tzn. Musisz określić górną i dolną pozycję zakotwiczenia). Naprawia również błąd, gdy wyświetlasz to na urządzeniach mobilnych (musisz sprawdzić lewą pozycję przewijania, w przeciwnym razie div zniknie z ekranu).

function moveScroller() {
    var move = function() {
        var st = $(window).scrollTop();
        var sl = $(window).scrollLeft();
        var ot = $("#scroller-anchor-top").offset().top;
        var ol = $("#scroller-anchor-top").offset().left;
        var bt = $("#scroller-anchor-bottom").offset().top;
        var s = $("#scroller");
        if(st > ot) {
            if (st < bt - 280) //280px is the approx. height for the sticky div
            {
                s.css({
                    position: "fixed",
                    top: "0px",
                    left: ol-sl
                }); 
            }
            else
            {
                s.css({
                    position: "fixed",
                    top: bt-st-280,
                    left: ol-sl
                }); 
            }
        } else {
            s.css({
                position: "relative",
                top: "",
                left: ""
            });

        }
    };
    $(window).scroll(move);
    move();
}


0

Informacje podane w celu udzielenia odpowiedzi na inne pytanie mogą być dla ciebie pomocne, Evan:

Sprawdź, czy element jest widoczny po przewinięciu

Zasadniczo chcesz zmodyfikować styl elementu, aby ustawić go na stały dopiero po sprawdzeniu, czy wartość document.body.scrollTop jest równa lub większa niż górna część elementu.


0

Akceptowana odpowiedź działa, ale nie wraca do poprzedniej pozycji, jeśli przewiniesz ją powyżej. Po umieszczeniu zawsze jest przyklejany do góry.

  $(window).scroll(function(e) {
    $el = $('.fixedElement');
    if ($(this).scrollTop() > 42 && $el.css('position') != 'fixed') {
      $('.fixedElement').css( 'position': 'fixed', 'top': '0px');

    } else if ($(this).scrollTop() < 42 && $el.css('position') != 'relative') {
      $('.fixedElement').css( 'relative': 'fixed', 'top': '42px');
//this was just my previous position/formating
    }
  });

Odpowiedź Jleiediewa mogłaby zadziałać, ale nie byłem w stanie zmusić go do działania. Jego przykładowa strona również nie działała (dla mnie).


0

Możesz dodać 3 dodatkowe wiersze, więc gdy użytkownik przewinie z powrotem na górę, div pozostanie na swoim starym miejscu:

Oto kod:

if ($(this).scrollTop() < 200 && $el.css('position') == 'fixed'){
    $('.fixedElement').css({'position': 'relative', 'top': '200px'});
}

0

Mam linki ustawione w div, więc jest to pionowa lista linków liter i cyfr.

#links {
    float:left;
    font-size:9pt;
    margin-left:0.5em;
    margin-right:1em;
    position:fixed;
    text-align:center;
    width:0.8em;
}

Następnie ustawiam tę przydatną funkcję jQuery, aby zapisać załadowaną pozycję, a następnie zmieniam pozycję na stałą podczas przewijania poza tę pozycję.

UWAGA: działa to tylko wtedy, gdy linki są widoczne podczas ładowania strony !!

var listposition=false;
jQuery(function(){
     try{
        ///// stick the list links to top of page when scrolling
        listposition = jQuery('#links').css({'position': 'static', 'top': '0px'}).position();
        console.log(listposition);
        $(window).scroll(function(e){
            $top = $(this).scrollTop();
            $el = jQuery('#links');
            //if(typeof(console)!='undefined'){
            //    console.log(listposition.top,$top);
            //}
            if ($top > listposition.top && $el.css('position') != 'fixed'){
                $el.css({'position': 'fixed', 'top': '0px'});
            }
            else if ($top < listposition.top && $el.css('position') == 'fixed'){
                $el.css({'position': 'static'});
            }
        });

    } catch(e) {
        alert('Please vendor admin@mydomain.com (Myvendor JavaScript Issue)');
    }
});

0

Wykorzystałem niektóre z powyższych prac, aby stworzyć tę technologię. Trochę go poprawiłem i pomyślałem, że podzielę się swoją pracą. Mam nadzieję że to pomoże.

Kod jsfuddle

function scrollErrorMessageToTop() {
    var flash_error = jQuery('#flash_error');
    var flash_position = flash_error.position();

    function lockErrorMessageToTop() {
        var place_holder = jQuery("#place_holder");
        if (jQuery(this).scrollTop() > flash_position.top && flash_error.attr("position") != "fixed") {
            flash_error.css({
                'position': 'fixed',
                'top': "0px",
                "width": flash_error.width(),
                "z-index": "1"
            });
            place_holder.css("display", "");
        } else {
            flash_error.css('position', '');
            place_holder.css("display", "none");
        }

    }
    if (flash_error.length > 0) {
        lockErrorMessageToTop();

        jQuery("#flash_error").after(jQuery("<div id='place_holder'>"));
        var place_holder = jQuery("#place_holder");
        place_holder.css({
            "height": flash_error.height(),
            "display": "none"
        });
        jQuery(window).scroll(function(e) {
            lockErrorMessageToTop();
        });
    }
}
scrollErrorMessageToTop();​

Jest to nieco bardziej dynamiczny sposób przewijania. To wymaga trochę pracy i w pewnym momencie zmienię to w pluging, ale to właśnie wymyśliłem po godzinie pracy.


0

W javascript możesz:

var element = document.getElementById("myid");
element.style.position = "fixed";
element.style.top = "0%";

0

Nie jest to dokładne rozwiązanie, ale świetna alternatywa do rozważenia

Ten CSS do góry paska przewijania ekranu . Rozwiązano cały problem z TYLKO CSS , BEZ JavaScript, BEZ JQuery, Bez pracy mózgu ( lol ).

Ciesz się moim skrzypkiem : D wszystkie kody są tam zawarte :)

CSS

#menu {
position: fixed;
height: 60px;
width: 100%;
top: 0;
left: 0;
border-top: 5px solid #a1cb2f;
background: #fff;
-moz-box-shadow: 0 2px 3px 0px rgba(0, 0, 0, 0.16);
-webkit-box-shadow: 0 2px 3px 0px rgba(0, 0, 0, 0.16);
box-shadow: 0 2px 3px 0px rgba(0, 0, 0, 0.16);
z-index: 999999;
}

.w {
    width: 900px;
    margin: 0 auto;
    margin-bottom: 40px;
}<br type="_moz">

Umieść treść wystarczająco długo, abyś mógł zobaczyć efekt tutaj :) Aha, i jest tam też referencja, ponieważ zasługuje na uznanie

TYLKO CSS Pasek przewijania na górze ekranu


Trochę offtopic;)
Tokk

Nie jestem przeciwny dobremu rozwiązaniu, ale kod w twojej odpowiedzi pozwala stworzyć coś w rodzaju menu, które zawsze będzie na wierzchu. Ale to nie było pytanie ...
Tokk

po prostu naprawiasz div i nie robisz nic lepkiego podczas przewijania.
yogihosting

0

Oto przykład, który używa wtyczki widocznej dla jquery: http://jsfiddle.net/711p4em4/ .

HTML:

<div class = "wrapper">
    <header>Header</header>
    <main>
        <nav>Stick to top</nav>
        Content
    </main>
    <footer>Footer</footer>
</div>

CSS:

* {
    margin: 0;
    padding: 0;
}

body {
    background-color: #e2e2e2;
}

.wrapper > header,
.wrapper > footer {
    font: 20px/2 Sans-Serif;
    text-align: center;
    background-color: #0040FF;
    color: #fff;
}

.wrapper > main {
    position: relative;
    height: 500px;
    background-color: #5e5e5e;
    font: 20px/500px Sans-Serif;
    color: #fff;
    text-align: center;
    padding-top: 40px;
}

.wrapper > main > nav {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    font: 20px/2 Sans-Serif;
    color: #fff;
    text-align: center;
    background-color: #FFBF00;
}

.wrapper > main > nav.fixed {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
}

JS (zawiera wtyczkę widoczną dla jquery):

(function($){

    /**
     * Copyright 2012, Digital Fusion
     * Licensed under the MIT license.
     * http://teamdf.com/jquery-plugins/license/
     *
     * @author Sam Sehnert
     * @desc A small plugin that checks whether elements are within
     *       the user visible viewport of a web browser.
     *       only accounts for vertical position, not horizontal.
     */
    var $w = $(window);
    $.fn.visible = function(partial,hidden,direction){

        if (this.length < 1)
            return;

        var $t        = this.length > 1 ? this.eq(0) : this,
            t         = $t.get(0),
            vpWidth   = $w.width(),
            vpHeight  = $w.height(),
            direction = (direction) ? direction : 'both',
            clientSize = hidden === true ? t.offsetWidth * t.offsetHeight : true;

        if (typeof t.getBoundingClientRect === 'function'){

            // Use this native browser method, if available.
            var rec = t.getBoundingClientRect(),
                tViz = rec.top    >= 0 && rec.top    <  vpHeight,
                bViz = rec.bottom >  0 && rec.bottom <= vpHeight,
                lViz = rec.left   >= 0 && rec.left   <  vpWidth,
                rViz = rec.right  >  0 && rec.right  <= vpWidth,
                vVisible   = partial ? tViz || bViz : tViz && bViz,
                hVisible   = partial ? lViz || rViz : lViz && rViz;

            if(direction === 'both')
                return clientSize && vVisible && hVisible;
            else if(direction === 'vertical')
                return clientSize && vVisible;
            else if(direction === 'horizontal')
                return clientSize && hVisible;
        } else {

            var viewTop         = $w.scrollTop(),
                viewBottom      = viewTop + vpHeight,
                viewLeft        = $w.scrollLeft(),
                viewRight       = viewLeft + vpWidth,
                offset          = $t.offset(),
                _top            = offset.top,
                _bottom         = _top + $t.height(),
                _left           = offset.left,
                _right          = _left + $t.width(),
                compareTop      = partial === true ? _bottom : _top,
                compareBottom   = partial === true ? _top : _bottom,
                compareLeft     = partial === true ? _right : _left,
                compareRight    = partial === true ? _left : _right;

            if(direction === 'both')
                return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop)) && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
            else if(direction === 'vertical')
                return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop));
            else if(direction === 'horizontal')
                return !!clientSize && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
        }
    };

})(jQuery);

$(function() {
    $(window).scroll(function() {
        $(".wrapper > header").visible(true) ?
            $(".wrapper > main > nav").removeClass("fixed") :
            $(".wrapper > main > nav").addClass("fixed");
    });
});

-1

lepki, dopóki stopka nie dotknie div:

function stickyCostSummary() {
    var stickySummary = $('.sticky-cost-summary');
    var scrollCostSummaryDivPosition = $(window).scrollTop();
    var footerHeight = $('#footer').height();
    var documentHeight = $(document).height();
    var costSummaryHeight = stickySummary.height();
    var headerHeight = 83;
    var footerMargin = 10;
    var scrollHeight = 252;
    var footerPosition = $('#footer').offset().top;

    if (scrollCostSummaryDivPosition > scrollHeight && scrollCostSummaryDivPosition <= (documentHeight - footerHeight - costSummaryHeight - headerHeight - footerMargin)) {
        stickySummary.removeAttr('style');
        stickySummary.addClass('fixed');

    } else if (scrollCostSummaryDivPosition > (documentHeight - footerHeight - costSummaryHeight - headerHeight - footerMargin)) {
        stickySummary.removeClass('fixed');
        stickySummary.css({
          "position" : "absolute",
          "top" : (documentHeight - footerHeight - costSummaryHeight - headerHeight - footerMargin - scrollHeight) + "px"
      });
    } else {
        stickySummary.removeClass('fixed');
        stickySummary.css({
            "position" : "absolute",
            "top" : "0"
        });
    }
}

$window.scroll(stickyCostSummary);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.