滚动div中绝对定位的div跳跃

时间:2013-06-09 11:28:21

标签: jquery css html scroll

我知道有类似的问题,但到目前为止我还没有办法解决我的问题。这jsfiddle反映了我的要求。

为了解释,div中有几个垂直堆叠的视图div(溢出)。每个view-div都有一个label-div,应该显示在左上角。如果view-divs水平滚动,标签应保持在视图中。当视图垂直滚动时,向上消失的视图应该将标签向下推,直到它完全消失。

这个jsfiddle示例中没有的另一个要求是view-divs可以垂直调整大小(我准备好了代码,但我认为这个例子太大了。)

现在,我实施它的方式不起作用。标签移动不够顺畅。我真的希望它们粘在容器div的边缘。此外,当您快速向上滚动时,标签不会落在左上角。

其他一些SO问题/答案表明我应该在固定和绝对定位之间切换,具体取决于滚动方向。但我认为这不会起作用,因为用户可以同时水平和垂直拖动滚动背景。

我希望$labels.css({"left" : scrLeft})方法能够起作用,这似乎是合理的。 :-)我试过简化my example,但是那里的运动也太过分了。

有什么想法吗?谢谢!

2 个答案:

答案 0 :(得分:1)

概念验证解决方案

这是一个很小的问题,它真正迫使你去思考控制布局几何的各种重叠坐标系。

以下是 jQuery

//handle scrolling
var $labels = $(".label");

$("#container").on("scroll", function () {

    //horizontal
    var scrLeft = $(this).scrollLeft();
    $labels.css({
        "left": scrLeft
    });

    //vertical
    var scrollTop    = $("#container").scrollTop();
    var containerTop = $('#container').position().top;
    var innerTop = $('#inner_container').position().top;
    var views = $("#inner_container .view");
    var diff = 0;
    var heightAggr = 0;

    if (scrollTop == 0) {
        views.children(".label").css({
            "top": 0
        });
    }

    views.children(".label").removeClass('highlight');
    for (var i = 0; i < views.length; i += 1) {
        var view = $(views[i])
        var viewHeight = view.outerHeight();
        var viewTop = view.offset().top;

        /* This is the key parameter to test... 
           getting this relationship right took a lot of effort,
           everything else was relatively easy... */
        diff = scrollTop - viewTop + innerTop;

        if (diff>0) {
            view.children(".label").addClass('highlight');
            var labelOffset = scrollTop - heightAggr;
            var maxOffset = view.height() 
                            - view.children(".label").outerHeight();

            /* The following pins the label to the bottom of the
               view when view is about to scroll off the screen... */
            var labelPosition = Math.min(labelOffset,maxOffset); 

            view.children(".label").css({
            "top": labelPosition
            });
        } else {
            view.children(".label").css({ /* Clean up when         */
            "top": 0                      /* reverse scrolling ... */
            });
        }
        /* will allow .view with variable heights... */
        heightAggr += viewHeight; 
    }
});

演示小提琴位于:http://jsfiddle.net/audetwebdesign/HRnCf/

浏览器免责声明

我只在Firefox中测试过这个...

答案 1 :(得分:0)

你应该使用固定位置:

http://jsfiddle.net/mHWJH/1/

var $label1 = $("#label1"),
    offsetTop = $label1.offset().top,
    offsetLeft = $label1.offset().left,
    $label2 = $("#label2"),
    offsetTop2 = $label2.offset().top,
    offsetLeft2 = $label2.offset().left;

$("#container").on("scroll", function() {

    var scrLeft = $(this).scrollLeft();
    $label1.css({
        position:'fixed',
        top:offsetTop,
        left:offsetLeft
    });
     $label2.css({
        position:'fixed',
        top:offsetTop2,
        left:offsetLeft2
    });
});