Javascript 在页脚停止固定位置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8653025/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 06:56:09  来源:igfitidea点击:

Stop fixed position at footer

javascriptjquerycssscrollfixed

提问by scferg5

I'm looking for a solution to the popular issue of stopping a fixed object at the footer of the page.

我正在寻找解决在页面页脚停止固定对象的流行问题的方法。

I basically have a fixed "share" box in the bottom left corner of the screen and I don't want it to scroll over the footer, so I need it to stop about 10pxabove the footer.

我基本上在屏幕的左下角有一个固定的“共享”框,我不希望它在页脚上滚动,所以我需要它10px在页脚上方停止。

I've looked at other questions here as well as others. The closest/most simple demo I could find is http://jsfiddle.net/bryanjamesross/VtPcm/but I couldn't get it to work with my situation.

我在这里以及其他人都看过其他问题。我能找到的最接近/最简单的演示是http://jsfiddle.net/bryanjamesross/VtPcm/但我无法让它适应我的情况。

Here's the html for the share box:

这是共享框的html:

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

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

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

...and the CSS:

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

The footer is #footerand it doesn't have a fixed height, if that makes any difference.

页脚是#footer并且它没有固定的高度,如果这有什么不同的话。

If someone could assist me in creating a simple jQuery solution for this, I'd much appreciate it!

如果有人能帮助我为此创建一个简单的 jQuery 解决方案,我将不胜感激!

回答by Sang

Live demo

现场演示

first, check its offset every time you scroll the page

首先,每次滚动页面时检查其偏移量

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

and make its position absolute if it has been downed under 10px before the footer.

如果它在页脚之前低于 10 像素,则使其位置绝对。

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
}

notice that #social-float's parent should be sibling of the footer

请注意,它#social-float的父节点应该是页脚的兄弟节点

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

good luck :)

祝你好运 :)

回答by user1097431

I've just solved this problem on a site I'm working on, and thought I would share it in the hope it helps someone.

我刚刚在我正在开发的网站上解决了这个问题,并认为我会分享它,希望它可以帮助某人。

My solution takes the distance from the footer to the top of the page - if the user has scrolled further than this, it pulls the sidebar back up with a negative margin.

我的解决方案需要从页脚到页面顶部的距离 - 如果用户滚动得比这更远,它会以负边距将侧边栏拉回。

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

回答by Lionel Paulus

Here is the @Sang solution but without Jquery.

这是@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>

回答by Emanuele Pane

I ran into this same issue recently, posted the my solution also here: Preventing element from displaying on top of footer when using position:fixed

我最近遇到了同样的问题,也在此处发布了我的解决方案: 使用位置时防止元素显示在页脚顶部:固定

You can achieve a solution leveraging the positionproperty of the element with jQuery, switching between the default value (staticfor divs), fixedand absolute. You will also need a container element for your fixed element. Finally, in order to prevent the fixed element to go over the footer, this container element can't be the parent of the footer.

您可以利用positionjQuery 的元素属性实现解决方案,在默认值 ( staticfor divs)fixedabsolute. 您还需要一个用于固定元素的容器元素。最后,为了防止固定元素越过footer,这个容器元素不能是footer的父元素。

The javascript part involves calculating the distance in pixels between your fixed element and the top of the document, and comparing it with the current vertical position of the scrollbar relatively to the window object (i.e. the number of pixels above that are hidden from the visible area of the page) every time the user scrolls the page. When, on scrolling down, the fixed element is about to disappear above, we change its position to fixed and stick on top of the page.

javascript 部分涉及计算固定元素与文档顶部之间的像素距离,并将其与滚动条相对于窗口对象的当前垂直位置(即上方隐藏在可见区域的像素数)进行比较页面)每次用户滚动页面。当向下滚动时,固定元素即将消失在上方时,我们将其位置更改为固定并粘在页面顶部。

This causes the fixed element to go over the footer when we scroll to the bottom, especially if the browser window is small. Therefore, we will calculate the distance in pixels of the footer from the top of the document and compare it with the height of the fixed element plus the vertical position of the scrollbar: when the fixed element is about to go over the footer, we will change its position to absolute and stick at the bottom, just over the footer.

当我们滚动到底部时,这会导致固定元素越过页脚,尤其是在浏览器窗口很小的情况下。因此,我们将计算页脚距文档顶部的像素距离,并将其与固定元素的高度加上滚动条的垂直位置进行比较:当固定元素即将越过页脚时,我们将将其位置更改为绝对位置并停留在底部,就在页脚上方。

Here's a generic example.

这是一个通用示例。

The HTML structure:

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>  

The CSS:

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 */
}

The JS:

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

 });

回答by zookastos

This worked for me -

这对我有用-

HTML -

HTML -

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

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

CSS -

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 -

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

Now call this function like this -

现在像这样调用这个函数 -

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

PS - The Jquery functions are copied from an answer to another similar question on stackoverflow, but it wasn't working for me fully. So I modified it to these functions, as they are shown here. I think the position etc attributes to your divs will depend on how the divs are structured, who their parents and siblings are.

PS - Jquery 函数是从关于 stackoverflow 的另一个类似问题的答案中复制的,但它并不完全适合我。因此,我将其修改为这些功能,如下所示。我认为你的 div 的位置等属性将取决于 div 的结构,他们的父母和兄弟姐妹是谁。

The above function works when both sideNote and footer-wraps are direct siblings.

当 sideNote 和 footer-wraps 都是直接兄弟时,上述函数有效。

回答by Ali Klein

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

回答by Arthur M

You can now use

您现在可以使用

#myObject{
  position:sticky;
}

Hope this helps..

希望这可以帮助..

回答by Brainmaniac

I went with a modification of @user1097431 's answer:

我修改了@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
   });
 };
};

回答by young sir x

I've made some changes to the second most popular answer as i found this worked better for me. The changes use window.innerHeight as it is more dynamic than adding your own height for the nav (above used + 570). this allows the code to work on mobile, tablet and desktop dynamicly.

我对第二个最受欢迎的答案进行了一些更改,因为我发现这对我来说效果更好。更改使用 window.innerHeight,因为它比为导航添加您自己的高度更具动态性(以上使用 + 570)。这允许代码在移动设备、平板电脑和台式机上动态运行。

$(window).scroll(() => {
            //Distance from top fo document to top of footer
            topOfFooter = $('#footer').position().top;
             // Distance user has scrolled from top + windows inner height
             scrollDistanceFromTopOfDoc = $(document).scrollTop() + window.innerHeight;
             // Difference between the two.
             scrollDistanceFromTopOfFooter = scrollDistanceFromTopOfDoc - topOfFooter; 
            // If user has scrolled further than footer,
              if (scrollDistanceFromTopOfDoc > topOfFooter) {
                // add margin-bottom so button stays above footer.
                $('#floating-button').css('margin-bottom',  0 + scrollDistanceFromTopOfFooter);
              } else  {
                // remove margin-bottom so button goes back to the bottom of the page
                $('#floating-button').css('margin-bottom', 0);
              }
            });

回答by Lionel B

A pure css solution

纯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>

And css here

和这里的css

#outer-container {
    position: relative;
}

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

#social-float {
    position: absolute;
    bottom: 0px;
}