Остановить фиксированное положение в нижнем колонтитуле - PullRequest
38 голосов
/ 28 декабря 2011

Я ищу решение популярной проблемы остановки фиксированного объекта в нижнем колонтитуле страницы.

У меня в основном есть фиксированное поле «Поделиться» в левом нижнем углу экрана, и я не хочу, чтобы оно прокручивалось в нижнем колонтитуле, поэтому мне нужно, чтобы оно останавливалось примерно на 10px над нижним колонтитулом.

Я смотрел на другие вопросы здесь, а также на другие. Самое близкое / простое демо, которое я смог найти, это http://jsfiddle.net/bryanjamesross/VtPcm/, но я не смог заставить его работать в моей ситуации.

Вот HTML-код для поля общего доступа:

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

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

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

... и 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;
}

Нижний колонтитул - #footer, и он не имеет фиксированной высоты, если это имеет какое-либо значение.

Если бы кто-то мог помочь мне в создании простого решения jQuery для этого, я был бы очень признателен за это!

Ответы [ 9 ]

58 голосов
/ 28 декабря 2011

Демонстрационная версия

сначала проверяйте его смещение при каждой прокрутке страницы

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

и сделайте свою позицию абсолютной, если она была снижена до 10px до нижнего колонтитула.

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
}

обратите внимание, что родительский номер #social-float должен быть родным от нижнего колонтитула

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

удачи:)

20 голосов
/ 17 января 2012

Я только что решил эту проблему на сайте, над которым я работаю, и решил поделиться им в надежде, что это кому-нибудь поможет.

Мое решение берет расстояние от нижнего колонтитула до верхней части страницы - если пользователь прокрутил дальше, чем это, он поднимает боковую панель вверх с отрицательным полем.

$(window).scroll(() => { 
  // Distance from top of document to top of footer.
  topOfFooter = $('#footer').position().top;
  // Distance user has scrolled from top, adjusted to take in height of sidebar (570 pixels inc. padding).
  scrollDistanceFromTopOfDoc = $(document).scrollTop() + 570;
  // Difference between the two.
  scrollDistanceFromTopOfFooter = scrollDistanceFromTopOfDoc - topOfFooter;

  // If user has scrolled further than footer,
  // pull sidebar up using a negative margin.
  if (scrollDistanceFromTopOfDoc > topOfFooter) {
    $('#cart').css('margin-top',  0 - scrollDistanceFromTopOfFooter);
  } else  {
    $('#cart').css('margin-top', 0);
  }
});
5 голосов
/ 07 сентября 2016

Вот решение @Sang, но без 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>
4 голосов
/ 29 мая 2013

Я недавно столкнулся с этой же проблемой, опубликовал мое решение также здесь: Предотвращение отображения элемента в верхней части нижнего колонтитула при использовании позиции: исправлено

Вы можете достичь решения, используя свойство position элемента с помощью jQuery, переключаясь между значением по умолчанию (static для divs), fixed и absolute. Вам также понадобится элемент контейнера для вашего фиксированного элемента. Наконец, для предотвращения перехода фиксированного элемента через нижний колонтитул этот элемент контейнера не может быть родительским для нижнего колонтитула.

Часть javascript включает в себя вычисление расстояния в пикселях между вашим фиксированным элементом и верхней частью документа и сравнение его с текущей вертикальной позицией полосы прокрутки относительно объекта окна (т. Е. Числа пикселей выше, которые скрыты от видимая область страницы) каждый раз, когда пользователь прокручивает страницу. Когда при прокрутке вниз фиксированный элемент собирается исчезнуть выше, мы меняем его положение на фиксированный и придерживаемся сверху страницы.

Это заставляет фиксированный элемент проходить через нижний колонтитул, когда мы прокручиваем вниз, особенно если окно браузера маленькое. Поэтому мы вычислим расстояние в пикселях нижнего колонтитула от верхней части документа и сравним его с высотой фиксированного элемента плюс вертикальное положение полосы прокрутки: когда фиксированный элемент собирается пройти над нижним колонтитулом, мы будем измените его положение на абсолютное и вставьте внизу, чуть выше нижнего колонтитула.

Вот общий пример.

Структура 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 голосов
/ 08 июля 2016

Это сработало для меня -

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

Теперь вызовите эту функцию следующим образом -

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

PS - Функции Jquery скопированы из ответа на другой похожий вопрос о stackoverflow, но он не работал для меня полностью. Поэтому я изменил его для этих функций, как они показаны здесь. Я думаю, что атрибуты позиции и т. Д. Будут зависеть от того, как структурированы div, кто их родители и братья и сестры.

Вышеприведенная функция работает, когда как sideNote, так и нижний колонтитул являются прямыми родственниками.

1 голос
/ 09 января 2019

Теперь вы можете использовать

#myObject{
  position:sticky;
}

Надеюсь, это поможет ..

0 голосов
/ 26 марта 2019

Чистый раствор css

<div id="outer-container">
    <div id="scrollable">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam in vulputate turpis. Curabitur a consectetur libero. Nulla ac velit nibh, ac lacinia nulla. In sed urna sit amet mauris vulputate viverra et et eros. Pellentesque laoreet est et neque euismod a bibendum velit laoreet. Nam gravida lectus nec purus porttitor porta. Vivamus tempor tempus auctor. Nam quis porttitor ligula. Vestibulum rutrum fermentum ligula eget luctus. Sed convallis iaculis lorem non adipiscing. Sed in egestas lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nunc dictum, lacus quis venenatis ultricies, turpis lorem bibendum dui, quis bibendum lacus ante commodo urna. Fusce ut sem mi, nec molestie tortor. Mauris eu leo diam. Nullam adipiscing, tortor eleifend pellentesque gravida, erat tellus vulputate orci, quis accumsan orci ipsum sed justo. Proin massa massa, pellentesque non tristique non, tristique vel dui. Vestibulum at metus at neque malesuada porta et vitae lectus.
    </div>
    <button id="social-float">The button</button>
</div>
<div>
Footer
</div>
</div>

И CSS здесь

#outer-container {
    position: relative;
}

#scrollable {
    height: 100px;
    overflow-y: auto;
}

#social-float {
    position: absolute;
    bottom: 0px;
}
0 голосов
/ 13 октября 2018
$(window).scroll(() => {
    const footerToTop = $('.your-footer').position().top;
    const scrollTop = $(document).scrollTop() + $(window).height();
    const difference = scrollTop - footerToTop;
    const bottomValue = scrollTop > footerToTop ? difference : 0;
    $('.your-fixed-element').css('bottom', bottomValue);
});
0 голосов
/ 24 октября 2017

Я пошел с модификацией ответа @ user1097431:

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