jQuery建议:如何将元素滚动到视图中来改进此功能?

时间:2009-07-11 14:38:37

标签: javascript jquery firefox refactoring scroll

我创建了一个函数,将给定的子元素滚动到其父元素中的视图中。它如下:

function keepScrolledOver( elem )
{
    frame = elem.parent();

    var scrollPos = frame.scrollTop();
    var offset = elem.attr( "offsetTop" );

    // If the element is scrolled too high...
    if( offset < scrollPos )
    {
        frame.scrollTop( offset );
        // frame.attr( "scrollTop", offset );
    }

    // If the element is scrolled too low...
    else
    {
        var frameHeight = frame.height();
        var offsetBottom = offset + elem.height();
        var scrollBottom = scrollPos + frameHeight;


        if( offsetBottom > scrollBottom )
        {
            // frame.attr( "scrollTop", offsetBottom );
            if( frameHeight < offsetBottom )
                frame.scrollTop( offsetBottom - frameHeight );
                // frame.attr( "scrollTop", offsetBottom - frameHeight );
        }
    }
}

到目前为止,对于我的Firefox网络应用程序(到目前为止我已经测试过Firefox,我的意思是),这非常有效。唯一的问题是,对于滚动得太低的元素,它总是倾向于在目标元素上滚动一点点而不是直到它的结尾。我不确定元素填充是否与某些事情有关,否则我的数学很糟糕。

任何人对如何改善这一点有什么好主意?

1 个答案:

答案 0 :(得分:1)

如果元素太高,则触发的代码部分效果很好,假设框架元素及其子元素相对定位。如果没有,它使用绝对偏移量,但不起作用。

对于元素太低时触发的部分,我假设当你说“它总是倾向于只是一点点滚过目标元素而不是直到它的结尾”时你指的是这个事实如果框架小于其偏移量,则元素被切断。请尝试以下方法:

// If the frame is less than or equal to the element's height
if( frameHeight <= elem.attr('height') ){
   //Scroll to it's offsetBottom - the total frameHeight, so that the full element will be displayed
   frame.scrollTop( offsetBottom - frameHeight ); 
}else {
   //Else, the element's height is less than the frame, so the entire element will be displayed if we just scroll to the element's offsetBottom.
   frame.scrollTop( offsetBottom );
}

我创建了一个HTML演示页面,如下所示,没有遇到任何其他问题。玩弄元素的高度,看看你是否可以让它破碎。我使用的是Firefox 3.5,一切都很酷。

    <button id="buttonTest1">Slide to Test1</button> <button id="buttonTest2">Slide to Test2</button>
<div style="position:relative;width:100%;height:620px;overflow:scroll;">
    <div style="position:relative;height:50px;"></div>
    <div id="childSlide1" style="width:50px;height:50px;position:relative;">Test</div>
    <div id="childSlide2" style="width:50px;height:50px;position:relative;top:850px;">Test2</div>
</div>


$(document).ready(function(){
    function keepScrolledOver( elem ){
        var frame = elem.parent();

        var scrollPos = frame.scrollTop();
        var offset = elem.attr( "offsetTop" );
        alert ('scrollPos: '+scrollPos+' offset: '+offset);
        //var jQoffset = elem.offset();
        //alert ('jQoffset: '+jQoffset.top+' '+jQoffset.left);
        // If the element is scrolled too high...
        if( offset < scrollPos )
        {
                alert ('scrollPos '+scrollPos+' is bigger than offset '+offset);
                frame.scrollTop( offset );
                // frame.attr( "scrollTop", offset );
        }

        // If the element is scrolled too low...
        else
        {
                var frameHeight = frame.height();
                var offsetBottom = offset + elem.height();
                var scrollBottom = scrollPos + frameHeight;
                alert('frameHeight: '+frameHeight+' offsetBottom: '+offsetBottom+' scrollBottom: '+scrollBottom);


                if( offsetBottom > scrollBottom )
                {
                        // frame.attr( "scrollTop", offsetBottom );
                        if( frameHeight <= elem.attr('height') )
                        {
                            frame.scrollTop( offsetBottom - frameHeight );
                            // frame.attr( "scrollTop", offsetBottom - frameHeight );
                        }else {
                            frame.scrollTop( offsetBottom );
                        }
                }
        }
    }

    $('#buttonTest1').click(function(){
        var scrollElement = $('#childSlide1');
        keepScrolledOver(scrollElement);
    });

    $('#buttonTest2').click(function(){
        var scrollElement = $('#childSlide2');
        keepScrolledOver(scrollElement);
    });     
});