Javascript 高级jQuery粘性边栏

Javascript 高级jQuery粘性边栏,javascript,jquery,html,sidebar,sticky,Javascript,Jquery,Html,Sidebar,Sticky,我正在制作一个(粘性的)滚动边栏。问题是,大多数粘性边栏没有考虑到边栏可能比视口高(例如,如果许多项目添加到篮中(边栏))。这就是我想要解决的问题。这些是要求: 如果侧边栏的高度高于视口,则应 滚动浏览内容,div的底部应保持不变 向下滚动时视口的底部 如果边栏的高度高于视口,则divs 只有当您位于底部时,下方才应显示 页面 当用户向上滚动时,侧边栏会向后滚动到顶部并显示 粘回到视口的顶部 如果侧边栏的高度小于视口,则应为 向下滚动时,从顶部开始粘滞 因此,总的来说,相当多的功能,而不是那

我正在制作一个(粘性的)滚动边栏。问题是,大多数粘性边栏没有考虑到边栏可能比视口高(例如,如果许多项目添加到篮中(边栏))。这就是我想要解决的问题。这些是要求:

  • 如果侧边栏的高度高于视口,则应 滚动浏览内容,div的底部应保持不变 向下滚动时视口的底部

  • 如果边栏的高度高于视口,则divs 只有当您位于底部时,下方才应显示 页面

  • 当用户向上滚动时,侧边栏会向后滚动到顶部并显示 粘回到视口的顶部

  • 如果侧边栏的高度小于视口,则应为 向下滚动时,从顶部开始粘滞

因此,总的来说,相当多的功能,而不是那么简单(我认为)。我所看到的最接近我试图实现的是这个例子:但是代码的编写方式不适合我

到目前为止,这是我所做的:

我使用的jQuery代码是:

jQuery(document).ready(function($) {

var $sidebar   = $('.sidebar'),
    $content   = $('.content');

if ($sidebar.length > 0 && $content.length > 0) {
    var $window    = $(window),
        offset     = $sidebar.offset(),
        timer;

    $window.scroll(function() {
        clearTimeout(timer);
        timer = setTimeout(function() {
            if ($content.height() > $sidebar.height()) {
                var new_margin = $window.scrollTop() - offset.top;
                if ($window.scrollTop() > offset.top && ($sidebar.height()+new_margin) <= $content.height()) {
                    // Following the scroll...
                    $sidebar.stop().animate({ marginTop: new_margin });
                } else if (($sidebar.height()+new_margin) > $content.height()) {
                    // Reached the bottom...
                    $sidebar.stop().animate({ marginTop: $content.height()-$sidebar.height() });
                } else if ($window.scrollTop() <= offset.top) {
                    // Initial position...
                    $sidebar.stop().animate({ marginTop: 0 });
                }
            }
        }, 100); 
    });
}

});
jQuery(文档).ready(函数($){
变量$sidebar=$('.sidebar'),
$content=$('.content');
如果($sidebar.length>0&&$content.length>0){
变量$window=$(window),
偏移量=$sidebar.offset(),
定时器;
$window.scroll(函数(){
清除超时(计时器);
计时器=设置超时(函数(){
如果($content.height()>$sidebar.height()){
var new_margin=$window.scrollTop()-offset.top;
如果($window.scrollTop()>offset.top&($sidebar.height()+new_margin)$content.height()){
//到达底部。。。
$sidebar.stop().animate({marginTop:$content.height()-$sidebar.height()});

}如果($window.scrollTop()您正在使用边距移动粘性侧边栏,我发现这是处理当前询问的一种棘手方法(可能是一种更重的方法)

一般来说,我喜欢简单地向侧边栏添加一个类,使其成为“position:fixed”,这样浏览器就可以在保持锁定的同时完成繁重的工作

对于您当前的ask,您只需根据其向下滚动的距离以编程方式滚动该位置固定div(也设置为100%高度)。请看我的示例,看看这是否是您想要的效果:

以下是jquery:

jQuery(document).ready(function($) {

var $sidebar   = $('.sidebar'),
    $content   = $('.content');

//Since our CSS is going to monkey with the height as you scroll, I need to know the initial height.
var sidebarHeight = $sidebar.height();

if ($sidebar.length > 0 && $content.length > 0) {
    var $window    = $(window),
        offset     = $sidebar.offset(),
        timer;

    $window.scroll(function() {

        if ($content.height() > sidebarHeight) {
            var new_margin = $window.scrollTop() - offset.top;
            if ($window.scrollTop() > offset.top) {
                // Fix sidebar
                $sidebar.addClass("fixed");
                // Scroll it the appropriate ammount
                $sidebar.scrollTop(new_margin);            
            }else{
                $sidebar.removeClass("fixed");
            }
        }
    });
}

});

我相信这就是您想要的功能:

很抱歉,代码太乱了,但优化它应该相当容易。我还假设sidebar2(非粘性的)已经定义了高度,如果不是这样的话,您可以使用jquery检测它并使用.css选择器进行底部偏移

这是我的密码:

jQuery(document).ready(function() {

    var tmpWindow = $(window),
        sidebar = $('.sidebar'),
        content = $('.content'),
        sidebar1 = $('.sidebar1'),
        sidebar2 = $('.sidebar2'),
        viewportHeight = $(window).height(),
        sidebarHeight = sidebar.height(),
        sidebar1Height = sidebar1.height(),
        sidebar2Height = sidebar2.height(),
        offsetBottom;


    tmpWindow.scroll(function(){

        offsetBottom = content.height() - sidebar2Height;

        //if sidebar height is less that viewport
        if (viewportHeight > sidebarHeight) {
            sidebar.addClass('fixed');
        } 

        //sticky sidebar1
        if ((tmpWindow.scrollTop() + viewportHeight) > sidebar1Height ) {
            sidebar1.addClass('bottom');
        } else {
            sidebar1.removeClass('bottom');
        }

        //end of content, visible sidebar2
        if ((tmpWindow.scrollTop() + viewportHeight) > offsetBottom) {
            sidebar1.removeClass('bottom');
            sidebar1.addClass('fixedBottom');
        } else {
            sidebar1.removeClass('fixedBottom');
        }

    });

});

看看hcSticky,我只是在找这个。它是一种“完美的”sticky边栏,也可以通过选项模拟其他库

第一个演示可能是每个人都需要的,它独立于主要内容滚动一个容器(你可以在到达页面底部之前浏览整个侧边栏,也可以在到达页面顶部之前向上滚动侧边栏)


查看:

Hmmm。我自己的粘性头/元素库没有考虑到这一点。我想我有一个新问题要解决。:-)您好,很抱歉我延迟了回复,现在就看吧。我认为您的js fiddle有点问题,从代码中可以看出,它没有实现这一要求:如果边栏的高度高于视口,它应该在内容中滚动,滚动时div的底部应该贴在视口的底部g再往下。啊,抱歉-我的快速样式取决于浏览器的大小。不过,我想我的答案是适用的-在滚动时触发类,将导航栏切换到位置固定,并根据您计算的滚动偏移量实际滚动侧栏的内容。我尝试过的最好的库,谢谢!