javascript 使固定侧边栏从页面底部滚动 290 像素?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22549028/
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-10-27 23:20:53  来源:igfitidea点击:

Make fixed sidebar scroll 290px from bottom of page?

javascriptjquerycsswordpresssidebar

提问by J82

I am trying to create a sidebar that functions like the one on Vice.com. If you scroll down, the sidebar will become fixed at a certain point, and then when the sidebar reaches a certain point near the bottom of the site, it will then continue to scroll up with the rest of the site.

我正在尝试创建一个功能类似于 Vice.com 上的侧边栏。如果向下滚动,侧边栏将固定在某个点,然后当侧边栏到达站点底部附近的某个点时,它将继续与站点的其余部分一起向上滚动。

On my site, I am stuck on the second part which is getting the sidebar to continue scrolling up once it hits near the bottom. 290pxfrom the bottom to be exact.

在我的网站上,我被困在第二部分,即让侧边栏在靠近底部时继续向上滚动。290px准确地说是从底部开始。

Here is what I have so far:

这是我到目前为止所拥有的:

JavaScript

JavaScript

<script>
jQuery(window).scroll(function () {
    var threshold = 20;
 if (jQuery(window).scrollTop() >= 20)
     jQuery('#sidebar').addClass('fixed');
 else
     jQuery('#sidebar').removeClass('fixed');
});
</script>

CSS

CSS

#sidebar {
  margin: 0;
  position: absolute;
  right: 0;
  width: 220px;
}
#sidebar.fixed {
  margin-left: 720px;
  position:fixed;
  right: auto;
  top: 173px;
}

How can I make the fixed sidebar scroll up once it hits a certain point near the bottom?

一旦固定的侧边栏到达底部附近的某个点,如何使固定侧边栏向上滚动?



Edit #1

编辑 #1

Here is the updated code by Adam. I'm using a conditional statement for the pages that have a different threshold. Nothing happens when I use this code, meaning the sidebar doesn't get the fixedclass added and therefore scrolls up normally as if the code isn't even there. Also, I get a console error on this line if (scrollTop() >= 236) {saying that the "number is not a function".

这是 Adam 更新的代码。我正在对具有不同阈值的页面使用条件语句。当我使用此代码时没有任何反应,这意味着侧边栏没有fixed添加类,因此正常向上滚动,就好像代码根本不存在一样。另外,我在这一行收到一个控制台错误,if (scrollTop() >= 236) {说“数字不是函数”。

if (jQuery(document.body).hasClass("home")) {

    jQuery(window).scroll(function () {
        var sidebarHeight = jQuery('#sidebar').height(),
            containerHeight = jQuery('#container').height() + 173,
            scrollTop = jQuery(window).scrollTop(),
            clientHeight = scrollTop + jQuery(window).height(),
            threshold = 654;
        if (scrollTop() >= 654) {
            jQuery('#sidebar').addClass('fixed');
        } else if (containerHeight - scrollTop <= sidebarHeight) {
            jQuery('#sidebar').removeClass('fixed').addClass('bottom');
        }
    });

} else if (jQuery(document.body).hasClass("single") || jQuery(document.body).hasClass("page")) {

    jQuery(window).scroll(function () {
        var sidebarHeight = jQuery('#sidebar').height(),
            containerHeight = jQuery('#container').height() + 173,
            scrollTop = jQuery(window).scrollTop(),
            clientHeight = scrollTop + jQuery(window).height(),
            threshold = 20;
        if (scrollTop() >= 20) {
            jQuery('#sidebar').addClass('fixed');
        } else if (containerHeight - scrollTop <= sidebarHeight) {
            jQuery('#sidebar').removeClass('fixed').addClass('bottom');
        }
    });

} else {

    jQuery(window).scroll(function () {
        var sidebarHeight = jQuery('#sidebar').height(),
            containerHeight = jQuery('#container').height() + 173,
            scrollTop = jQuery(window).scrollTop(),
            clientHeight = scrollTop + jQuery(window).height(),
            threshold = 236;
        if (scrollTop() >= 236) {
            jQuery('#sidebar').addClass('fixed');
        } else if (containerHeight - scrollTop <= sidebarHeight) {
            jQuery('#sidebar').removeClass('fixed').addClass('bottom');
        }
    });

}

Below is the HTML structure as requested:

以下是请求的 HTML 结构:

<!-- BEGIN #masthead-->
<div id="masthead">
    <!-- #secondary-menu -->
    <div id="secondary-menu">

        <!-- .centered-menu -->
        <div class="centered-menu">
            <div class="latest-tweets"></div>
            <div id="search-bar"></div>
            <ul class="social-icons sf-js-enabled"></ul>
        </div>
        <!-- /.centered-menu -->

    </div>
    <!-- /#secondary-menu -->

    <!-- BEGIN #header-->
    <div id="header">

        <!-- #header-inner -->
        <div id="header-inner" class="clearfix">
            <div id="logo"></div>

            <!-- BEGIN #primary-menu -->
            <div id="primary-menu" class="clearfix">

                <!-- .left-menu -->
                <div class="left-menu split-menu"></div>
                <!-- /.left-menu -->

                <!-- .right-menu -->
                <div class="right-menu split-menu">
                    <div class="menu-menu-right-container"></div>
                <!-- /.right-menu -->   

            <!-- END #primary-menu -->
            </div>

        </div>
        <!-- /#header-inner -->

    <!-- END #header -->

    <!-- BEGIN #mobile-menu -->
    <div id="mobile-menu">
        <div id="mobile-inner"></div>
    </div>
    <!-- END #mobile-menu -->

    </div>

    <div id="categories-bar"></div>

</div>
<div id="masthead-space"></div>
<!-- END #masthead -->

<!-- BEGIN #wrapper-->
<div id="wrapper">

    <!-- BEGIN #page-->
    <div id="page">

        <div id="main" class="clearfix">

            <div id="container" class="clearfix">

                <!--BEGIN #content -->
                <div id="content">
                    <div id="sidebar"></div><!-- #sidebar --> 
                </div>

            </div>

        <!--END #main -->
        </div>

    <!--END #page -->
    </div>

<!--END #wrapper -->
</div>

<!--BEGIN #bottom -->
<div id="bottom">

    <!--BEGIN #footer -->
    <div id="footer"></div>

</div>

回答by Aramil Rey

My advise:

我的建议:

Create 2 CSS classes with the characteristics you want and toggle both after reaching the break point, 1 must be active at the begining.

创建 2 个具有您想要的特性的 CSS 类,并在到达断点后切换这两个类,1 个必须在开始时处于活动状态。

FIDDLE

小提琴

JS

JS

var changePoint = $('#reaching_the_top_of_this_element_activates_change').offset().top;

$(window).scroll(function ()  {
if ($(window).scrollTop() >= changePoint) {
    $('#sidebar').removeClass('blackStatic');
    $('#sidebar').addClass('redFixed');
}
else {
    $('#sidebar').addClass('blackStatic');
    $('#sidebar').removeClass('redFixed');
}

});

});

CSS

CSS

.blackStatic {
    position: static;
    background-color: black;
    color: red;
}
.redFixed {
    position: fixed;
    top: 0;
    background-color: red;
    color: black;
}

回答by Adam Merrifield

As I said in my comment, this may be off because I can't see the structure of the html right now. But something like this should work. We get the height of the scrollbar, container(+ the height of the header), and the height of the viewable area for the user or the client. So using maths, we can say that when the container- scrollTopis less than the height of the scrollbarwe need the scrollbar to stop being fixed. At this point we remove the fixed class and add the bottom class that just has 1 property. bottom: 0. Now as long as the scrollbar is inside of the container and the container has position: relativeit's bottom will be fixed to the bottom of the container.

正如我在评论中所说,这可能是关闭的,因为我现在看不到 html 的结构。但是这样的事情应该有效。我们得到scrollbar, container(+ 标题的高度) 的高度,以及用户或client. 所以使用数学,我们可以说当container-scrollTop小于 的高度时,scrollbar我们需要滚动条停止固定。此时我们移除固定类并添加仅具有 1 个属性的底部类。bottom: 0. 现在只要滚动条在容器内部并且容器有position: relative它的底部就会固定到容器的底部。

Javascript:

Javascript:

jQuery(window).scroll(function(){
    var sidebarHeight = jQuery('#sidebar').height(),
        containerHeight = jQuery('#container').height() + 173,
        scrollTop = jQuery(window).scrollTop(),
        clientHeight = scrollTop + jQuery(window).height(),
        threshold = 20;
    if(scrollTop >= 20){
        jQuery('#sidebar').addClass('fixed');
    }else if(containerHeight - scrollTop <= sidebarHeight){
        jQuery('#sidebar').removeClass('fixed').addClass('bottom');
    }
});

CSS:

CSS:

#sidebar.bottom {
    bottom: 0;
}

Let me know if this doesn't work for you, and update your question to have the html so this can be made more to your needs. Also you will have to deal with a user scrolling back up the page too, which this does not account for currently but it wouldn't be hard to add.

如果这对您不起作用,请告诉我,并更新您的问题以获取 html,以便可以更满足您的需求。此外,您还必须处理向上滚动页面的用户,这目前没有考虑在内,但添加起来并不难。

回答by Lee Gary

take a look at bootstrap-affix.js http://getbootstrap.com/2.3.2/javascript.html#affix

看看 bootstrap-affix.js http://getbootstrap.com/2.3.2/javascript.html#affix

It does exactly what you are asking for, and you can use html5 data-attributes to add the behaviors:

它完全符合您的要求,您可以使用 html5 数据属性来添加行为:

<div data-spy="affix" data-offset-top="200">...</div>

回答by Teo Dragovic

try this code (I used ID's according to your markup):

试试这个代码(我根据你的标记使用了 ID):

function sidebarScroll()
{
  var tmpWindow = $(window),
      wrapper = $('#wrapper').height(),
      header = $('#header').height(),
      sidebar = $('#sidebar'),
      offsetTop = sidebar.offset().top,
      offsetBottom;

  tmpWindow.scroll(function(){

    offsetBottom = (wrapper + header) - sidebar.height();

    if (tmpWindow.scrollTop() < offsetTop) {
      sidebar.removeClass('fixed bottom');
    } else if (tmpWindow.scrollTop() > offsetBottom) {
      sidebar.removeClass('fixed').addClass('bottom');
    } else {
      sidebar.removeClass('bottom').addClass('fixed');
    }
  });
}

sidebarScroll();

and this is the classes you need:

这是您需要的课程:

#wrapper {
  position: relative;
}
#sidebar {
  width: 220px;
  position: absolute;
  right: 0;
}

#sidebar.fixed {
  position: fixed;
  top: 0;
}

#sidebar.bottom {
  position: absolute;
  bottom: 0;
}

DEMO

演示

回答by Awesomolocity

The code you borrowed from Adam was copied wrong. You use scrollTop() instead of scrollTop. scrollTop is set to a number, so essentially, you're trying to do 20() (or whatever number scrollTop is set to)

你从 Adam 那里借来的代码被抄错了。您使用 scrollTop() 而不是 scrollTop。scrollTop 设置为一个数字,因此本质上,您正在尝试执行 20() (或设置为 scrollTop 的任何数字)

Edit: In order to reduce redundancy with your code, I rewrote it just to have the threshold set via ternary if statements:

编辑:为了减少代码的冗余,我重写了它只是为了通过三元 if 语句设置阈值:

jQuery(window).scroll(function () {
    var sidebarHeight = jQuery('#sidebar').height(),
    containerHeight = jQuery('#container').height() + 173,
    scrollTop = jQuery(window).scrollTop(),
    clientHeight = scrollTop + jQuery(window).height(),
    threshold = (jQuery(document.body).hasClass("home"))?654:((jQuery(document.body).hasClass("single") || jQuery(document.body).hasClass("page"))?20:236);
});

回答by Ghostff

<div class="main">
</div>
<div class="foot">
</div>
<div id="float">
<div class="float_content_head">
I was sending javascript to display
</div><div class="float_content">
d my issue was that I was sending javascript to display console messages. Even when I looked at the file in my browser (not through the application) it showed exactly as I expected it to (eg the extra tags weren't showing), but there were showing in the html/text output and were trying to be parsed. Hope this helps someone!I had a similar problem, and my issue was that I was sending tags we
</div>
</div>

Css
<style type="text/css">
#float{
    background: #fff;
    position:absolute;
    right:30px;
    top:20px;
    width:250px;
    padding:10px;
    border-radius: 6px;
    -webkit-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.43);
-moz-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.43);
box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.43);
}
.float_content_head{
    padding:10px;
    border-bottom: 1px solid #efefef;
    text-align:center;
}
.float_content{
    padding-top:10px;
}
.main{
    width: 800px;
    height: 800px;
    margin: 0 auto;
    border:1px solid #efefef;
    padding: 10px;
    background:#ccc;
}
.foot{
    width: 100%;
    height: 800px;
    margin: 0 auto;
    border:1px solid #efefef;
    padding: 10px;
    background:#096;
}
#box p{
    margin:0;
    padding:0;
}
</style>

JS
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript"> 
$(document).ready(function() {
var starting_position = $('#float').offset();
var top_padding = 50;
var bottom_limit = $('.foot').offset();
var box_height = $('#float').height() + 20;
$(window).scroll(function(){
var top_window = $(window).scrollTop();
if (top_window > starting_position.top && top_window < bottom_limit.top - box_height){
$('#float').stop().animate({top: top_window - starting_position.top + top_padding}, 400);
} else if (top_window > bottom_limit.top - starting_position.top - box_height){
$('#float').stop().animate({top: bottom_limit.top - starting_position.top - box_height }, 400);
} else { $('#float').stop().animate({top: 10 }, 400);           
}
});
});
</script>

回答by Timmah

It sounds like this is what you're after(excuse my IDs):

听起来这就是您所追求的(请原谅我的 ID):

$(document).ready(function() {
// Get the inital position of the menu
    var initialPos = $('#mainnav').offset().top;

//Bind scrolling or resizing
$(window).bind('scroll resize', function() {

// Get the distance from the top of the page to the top of the footer
    var footerTop = $('#footer').length > 0 ? $('#footer').offset().top : $('#footer').offset().top;

// Get the distance from the top of the page to the bottom of the menu
    var navBottom = $(window).scrollTop() + $('#mainnav').height() + 22;

// If the user scrolls further than the height of the header (this method allows for resizing with a max-width layout)
    if ($(window).scrollTop() > initialPos) {
        $('#mainnav').css({
            'position': 'fixed',

           // move the menu based on how far the user has scrolled, and if it exceed the height of the footer
            'top': (footerTop - navBottom > 0 ? 0 : footerTop - navBottom) + 'px',
            'left': ($('#wrapper02').offset().left - $(window).scrollLeft()) + 'px'
        });
    } else {
        $('#mainnav').css({
            'position': 'static'
        });
    }
});
});

回答by Kapil Barad

    <style>

     #wrap {
     width:100%;
     height:1000px;
 }  
 #sidebar {
    width:100px;
    height:100px;
    float:left;
    background-color:black;
    color:white;
    vertical-align:middle;
    text-align:center;
 }
    </style>

    <script>
     var offset = $("#sidebar").offset();
 var topPadding = 15;

 $(window).scroll(function () {
    if ($(window).scrollTop() > offset.top) {
        $("#sidebar").stop().animate({
            marginTop: $(window).scrollTop() - offset.top + topPadding
        });
    } else {
        $("#sidebar").stop().animate({
            marginTop: 0
        });
    }
 });

    </script>

    <div id='wrap'>
        <div id="sidebar">Side Bar</div>
    </div>

回答by Chad

An option would be waypoints.js, but I think you can do it with some simple jQuery. Waypoints may be for you, may not be... but it could be used in this scenario. So it's an option.

一个选项是 waypoints.js,但我认为你可以用一些简单的 jQuery 来完成。航路点可能适合您,也可能不适合……但它可以在这种情况下使用。所以这是一个选择。

Waypoints.js here: http://imakewebthings.com/waypoints/

Waypoints.js 在这里:http: //imakewebthings.com/waypoints/