2011-12-28 9 views
28

Szukam rozwiązania popularnego problemu zatrzymywania stałego obiektu w stopce strony.Zatrzymaj stałą pozycję w stopce

Zasadniczo mam stały kwadrat "akcji" w lewym dolnym rogu ekranu i nie chcę, aby przewijał stopkę, więc potrzebuję go, aby zatrzymać się nad stopką o wartości 10px.

Przyjrzałem się tu innym pytaniom, a także innym. Najbliższym/najprostszym demo, jakie mogłem znaleźć, jest http://jsfiddle.net/bryanjamesross/VtPcm/, ale nie mogłem go uruchomić z moją sytuacją.

Oto html na polu udostępniania:

<div id="social-float"> 
     <div class="sf-twitter"> 
      ... 
     </div> 

     <div class="sf-facebook"> 
      ... 
     </div> 

     <div class="sf-plusone"> 
      ... 
     </div> 
    </div> 

... i CSS:

#social-float{ 
position: fixed; 
bottom: 10px; 
left: 10px; 
width: 55px; 
padding: 10px 5px; 
text-align: center; 
background-color: #fff; 
border: 5px solid #ccd0d5; 
-webkit-border-radius: 2px; 
-moz-border-radius: 2px; 
border-radius: 2px; 
display: none; 
} 

Stopka jest #footer i nie mają stałą wysokość, jeśli sprawia, że jakakolwiek różnica.

Jeśli ktoś mógłby mi pomóc w stworzeniu prostego rozwiązania jQuery do tego, byłbym bardzo wdzięczny!

+0

Jaka jest różnica w Fiddle od tego, co trzeba? –

+0

Pasek boczny w skrzypcach nie jest ustalony względem okna przeglądarki. Nie wiem, może to być dokładnie ta sama koncepcja, ale bawiłem się nią i po prostu nie mogłem jej uruchomić z moim scenariuszem. Potrzebuję, żeby pudełko znajdowało się w lewym dolnym rogu okna, aż dotrze do stopki, gdzie następnie przewinie stronę. – scferg5

Odpowiedz

47

Live demo

najpierw sprawdzić jego przesunięcie za każdym razem przewijać stronę

$(document).scroll(function() { 
    checkOffset(); 
}); 

i dokonać jego pozycja absolutna jeżeli został zestrzelony pod 10px przed stopce.

function checkOffset() { 
    if($('#social-float').offset().top + $('#social-float').height() 
              >= $('#footer').offset().top - 10) 
     $('#social-float').css('position', 'absolute'); 
    if($(document).scrollTop() + window.innerHeight < $('#footer').offset().top) 
     $('#social-float').css('position', 'fixed'); // restore when you scroll up 
} 

zauważyć, że rodzic #social-float „s powinna być rodzeństwem stopce

<div class="social-float-parent"> 
    <div id="social-float"> 
     something... 
    </div> 
</div> 
<div id="footer"> 
</div> 

powodzenia :)

+0

Dzięki za odpowiedź. Teraz pudełko migocze, gdy przewija się nad stopką. Czy jest coś, co muszę zmienić w CSS? – scferg5

+0

oh, przepraszam, to dlatego, że styl pozycji ciągle się zmienia, odkąd został naprawiony. spróbuj zmienić operatora '>' z '> =' – Sang

+0

Ciągle miga :(Oto screencast z tego, co się dzieje, jeśli to pomoże: http: // youtu.be/aNnTARjYPOc – scferg5

16

Właśnie rozwiązać ten problem na miejscu pracuję nad, i pomyślałem, że podzielę się nim w nadziei, że komuś pomogę.

Moje rozwiązanie pobiera odległość od stopki na górę strony - jeśli użytkownik przewinął dalej, pociąga pasek boczny z powrotem do góry z marginesem ujemnym.

$(window).scroll(function() { 

// distance from top of footer to top of document 
footertotop = ($('#footer').position().top); 
// distance user has scrolled from top, adjusted to take in height of sidebar (570 pixels inc. padding) 
scrolltop = $(document).scrollTop()+570; 
// difference between the two 
difference = scrolltop-footertotop; 

// if user has scrolled further than footer, 
// pull sidebar up using a negative margin 

if (scrolltop > footertotop) { 

$('#cart').css('margin-top', 0-difference); 
} 

else { 
$('#cart').css('margin-top', 0); 
} 


}); 
+0

To działało znakomicie. Najlepsza odpowiedź była bez wyjścia, ponieważ mój rodzic z sidebarów nie był rodzeństwem stopki div. Ta odpowiedź jest mniej grymaśna co do kolejności stosów elementów div. – Dan382

+0

Doskonała odpowiedź. Pomagał mi w przewijaniu, który nakłada się na stopkę, kiedy przewijam w dół. Wielkie dzięki, proszę pana .. –

4

wpadłem na tej samej kwestii niedawno opublikował moje rozwiązanie również tutaj: Preventing element from displaying on top of footer when using position:fixed

można osiągnąć rozwiązanie wykorzystując właściwość elementu z jQuery position, przełączanie pomiędzy wartością domyślną (static dla divs), fixed i absolute. Potrzebny Ci będzie również element pojemnika na stały element. Na koniec, aby element stały nie mógł przejść nad stopką, ten element kontenera nie może być rodzicem stopki.

Część javascript obejmuje obliczanie odległości w pikselach między stałym elementem a górną częścią dokumentu i porównywanie go z bieżącą pozycją pionową paska przewijania względem obiektu okna (tj. Liczbę pikseli powyżej, które są ukryte z widocznego obszaru strony) za każdym razem, gdy użytkownik przewija stronę. Kiedy po przewinięciu w dół, stały element zniknie powyżej, zmieniamy jego położenie na stałe i umieszczamy go na górze strony.

Powoduje, że stały element przechodzi nad stopką, gdy przewijamy do dołu, szczególnie jeśli okno przeglądarki jest małe. Dlatego obliczymy odległość w pikselach stopki od górnej krawędzi dokumentu i porównamy ją z wysokością stałego elementu oraz pionową pozycją paska przewijania: gdy stały element przejdzie przez stopkę, zmieni swoją pozycję na absolutną i pozostanie na samym dole, tuż nad stopą.

Oto ogólny przykład.

Struktura HTML:

<div id="content"> 
    <div id="leftcolumn"> 
     <div class="fixed-element"> 
      This is fixed 
     </div> 
    </div> 
    <div id="rightcolumn">Main content here</div> 
    <div id="footer"> The footer </div> 
</div> 

CSS:

#leftcolumn { 
    position: relative; 
} 
.fixed-element { 
    width: 180px; 
} 
.fixed-element.fixed { 
    position: fixed; 
    top: 20px; 
} 
.fixed-element.bottom { 
    position: absolute; 
    bottom: 356px; /* Height of the footer element, plus some extra pixels if needed */ 
} 

JS:

// Position of fixed element from top of the document 
var fixedElementOffset = $('.fixed-element').offset().top; 
// Position of footer element from top of the document. 
// You can add extra distance from the bottom if needed, 
// must match with the bottom property in CSS 
var footerOffset = $('#footer').offset().top - 36; 

var fixedElementHeight = $('.fixed-element').height(); 

// Check every time the user scrolls 
$(window).scroll(function (event) { 

    // Y position of the vertical scrollbar 
    var y = $(this).scrollTop(); 

    if (y >= fixedElementOffset && (y + fixedElementHeight) < footerOffset) { 
     $('.fixed-element').addClass('fixed'); 
     $('.fixed-element').removeClass('bottom');   
    } 
    else if (y >= fixedElementOffset && (y + fixedElementHeight) >= footerOffset) { 
     $('.fixed-element').removeClass('fixed');   
     $('.fixed-element').addClass('bottom'); 
    } 
    else { 
     $('.fixed-element').removeClass('fixed bottom'); 
    } 

}); 
2

ten pracował dla mnie -

HTML -

<div id="sideNote" class="col-sm-3" style="float:right;"> 

</div> 
<div class="footer-wrap"> 
     <div id="footer-div"> 
     </div>  
</div> 

CSS -

#sideNote{right:0; margin-top:10px; position:fixed; bottom:0; margin-bottom:5px;} 

#footer-div{margin:0 auto; text-align:center; min-height:300px; margin-top:100px; padding:100px 50px;} 

jQuery -

function isVisible(elment) { 
    var vpH = $(window).height(), // Viewport Height 
     st = $(window).scrollTop(), // Scroll Top 
     y = $(elment).offset().top; 

    return y <= (vpH + st); 
} 

function setSideNotePos(){ 
    $(window).scroll(function() { 
     if (isVisible($('.footer-wrap'))) { 
      $('#sideNote').css('position','absolute'); 
      $('#sideNote').css('top',$('.footer-wrap').offset().top - $('#sideNote').outerHeight() - 100); 
     } else { 
      $('#sideNote').css('position','fixed'); 
      $('#sideNote').css('top','auto'); 
     } 
    }); 
} 

Teraz nazywają tę funkcję takiego -

$(document).ready(function() { 
    setSideNotePos(); 
}); 

PS - Funkcje Jquery są kopiowane z odpowiedzią na inny podobne pytanie na stackoverflow, ale to nie działa dla mnie w pełni. Więc zmodyfikowałem go do tych funkcji, jak pokazano tutaj. Myślę, że atrybuty pozycji itp do twoich div będą zależeć od tego, jak dzielą się struktury, kim są ich rodzice i rodzeństwo.

Powyższa funkcja działa, gdy zarówno sideNote, jak i stopki są bezpośrednimi rodzeństwami.

3

Oto rozwiązanie @Sang, ale bez Jquery.

var socialFloat = document.querySelector('#social-float'); 
 
var footer = document.querySelector('#footer'); 
 

 
function checkOffset() { 
 
    function getRectTop(el){ 
 
    var rect = el.getBoundingClientRect(); 
 
    return rect.top; 
 
    } 
 
    
 
    if((getRectTop(socialFloat) + document.body.scrollTop) + socialFloat.offsetHeight >= (getRectTop(footer) + document.body.scrollTop) - 10) 
 
    socialFloat.style.position = 'absolute'; 
 
    if(document.body.scrollTop + window.innerHeight < (getRectTop(footer) + document.body.scrollTop)) 
 
    socialFloat.style.position = 'fixed'; // restore when you scroll up 
 
    
 
    socialFloat.innerHTML = document.body.scrollTop + window.innerHeight; 
 
} 
 

 
document.addEventListener("scroll", function(){ 
 
    checkOffset(); 
 
});
div.social-float-parent { width: 100%; height: 1000px; background: #f8f8f8; position: relative; } 
 
div#social-float { width: 200px; position: fixed; bottom: 10px; background: #777; } 
 
div#footer { width: 100%; height: 200px; background: #eee; }
<div class="social-float-parent"> 
 
    <div id="social-float"> 
 
     float... 
 
    </div> 
 
</div> 
 
<div id="footer"> 
 
</div>

0

poszedłem z modyfikacją @ „s user1097431 odpowiedź:

function menuPosition(){ 
// distance from top of footer to top of document 
var footertotop = ($('.footer').position().top); 
// distance user has scrolled from top, adjusted to take in height of bar (42 pixels inc. padding) 
var scrolltop = $(document).scrollTop() + window.innerHeight; 
// difference between the two 
var difference = scrolltop-footertotop; 

// if user has scrolled further than footer, 
// pull sidebar up using a negative margin 
if (scrolltop > footertotop) { 
    $('#categories-wrapper').css({ 
     'bottom' : difference 
    }); 
}else{ 
    $('#categories-wrapper').css({ 
     'bottom' : 0 
    }); 
}; 
};