4

我目前正在严格限制我可以使用 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 中,所以我们可以利用它来发挥我们的优势。

4

2 回答 2

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? 因为我从那里拿了一些代码,部分描述了我的问题(用一个整洁的图表来启动)。

于 2012-10-18T12:21:59.043 回答
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 );

我没有包含 IEaddEvent方法,但是在这个基础上,你自己应该很容易做到这一点。

于 2012-10-17T14:50:46.223 回答