滚动到查看隐藏在持久标题下的元素

时间:2012-10-17 14:06:05

标签: javascript css header persistent

我目前在一些严格的限制下工作,我可以用JavaScript做什么(没有像jQuery这样的框架,而且没有发布Firefox 2.0)。

这是我的问题;我在页面顶部浮动了一个持久性标题。我有分散的输入元素(我们正在复制一份纸质表格,包括背景图片)。页面底部附近有一个字段可以选中(使用键盘标签按钮)并将焦点放在页面顶部的字段上。 Firefox会自动将字段“滚动到视图中”。但是,虽然浏览器认为该字段在视图中,但它实际上隐藏在持久标题下。

http://imageshack.us/a/img546/5561/scrollintoviewproblem.png

通过从页面上的其他位置点击“标签”来访问上面的蓝色字段。浏览器认为该字段已滚动到视图中,但事实上它隐藏在下面浮动持久性标题。

我正在寻找的是关于如何检测该字段位于此标题下方并相应滚动整个页面的想法。

我尝试了一些保证金和差价的变化。填充(请参阅http://code.stephenmorley.org/javascript/detachable-navigation/#considerations的其他注意事项),没有运气。每次我们专注于一个字段时,我也尝试调用JavaScript函数“scrollIntoView(element)”,但是考虑到表单上的字段数量(以及我们将它们对齐以匹配纸张的背景图像的事实)确切地说,这导致了一些相当严重的“跳跃”行为,当他们选择彼此接近的高度略有不同的领域时。

我可以更改持久标头的完成方式,只要它不需要太多努力。不幸的是,框架是不可能的,因为我们需要与持久性标头中的页面内容进行交互。

理想情况下,解决方案将在CSS中,但如果它解决了我的问题,我会接受JavaScript。

另外请注意,我们要求输入元素具有背景颜色,这意味着向它们添加填充会使背景颜色拉伸,从而隐藏背景图像的一部分。但是,输入元素在div中,因此我们可以使用它来发挥作用。

2 个答案:

答案 0 :(得分:2)

所以在做了一些搜索之后(感谢@Kraz在这条路线上使用scrollTo()建议)我找到了一个适合我的解决方案。

我已经动态地为每个元素添加了一个onFocus调用,因此它们总是调用scrollScreenArea(element)函数,该函数确定它们是隐藏在顶部标题下面还是太靠近页脚区域(这完全解决了另一个问题) ,使用相同的解决方案)。

/* This function finds an element's position relative to the top of the viewable area */
function findPosFromTop(node) { 
    var curtop = 0;
    var curtopscroll = 0;
    if (node.offsetParent) {
        do {
            curtop += node.offsetTop;
            curtopscroll = window.scrollY;
        } while (node = node.offsetParent);


    }
    return (curtop - curtopscroll);
}

/* This function scrolls the page to ensure that elements are
   always in the viewable area */
function scrollScreenArea(el) 
{ 

    var topOffset       = 200; //reserved space (in px) for header
    var bottomOffset    = 30;  //amount of space to leave at bottom
    var position        = findPosFromTop(el);
    //if hidden beneath header, scroll into view
    if (position < topOffset)
    {
        // to scroll up use a negative number
        scrollTo(el.offsetLeft,position-topOffset);
    }
    //if too close to bottom of view screen, scroll into view
    else if ((position + bottomOffset) > window.innerHeight)
    {
        scrollTo(0,window.scrollY+bottomOffset);
    }
}

如果您有任何疑问,请与我们联系。感谢@Kraz给我发送这个解决方案。

同样,我想引用Can I detect the user viewable area on the browser?,因为我从那里获取了一些代码并且部分描述了我的问题(使用一个简洁的图表来启动)。

答案 1 :(得分:0)

执行此操作的最简单方法是侦听每个元素的焦点事件,然后查看它是否在页面上。在纯JS中,它类似于:

var input = Array.prototype.slice.call(document.getElementsByTagName('input'));
for ( var i in input )
    input[i].addEventListener( 'focus', function (e) {
        var diff = 150 /* Header height */ - e.target.getBoundingClientRect().top;
        if ( diff > 0 ) {
            document.body.scrollTop += diff;
            document.documentElement && document.documentElement.scrollTop += diff;
        }
    }, false );

我没有包含IE addEvent方法,但在给定此基础的情况下自行制作它应该非常容易。