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 で問題が解決する場合は JavaScript を使用します。

もう 1 つの注意点として、入力要素には背景色が必要です。つまり、入力要素にパディングを追加すると背景色が引き伸ばされ、背景画像の一部が非表示になります。しかし、入力要素は div にあるため、これを有利に使用できる可能性があります。

4

2 に答える 2

2

したがって、さらに検索を行った後(scrollTo()の提案でこのルートをリードしてくれた@Krazに感謝します)、私に役立つ解決策を見つけました。

各要素に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に感謝します。

同様に、参照したいブラウザでユーザーが表示できる領域を検出できますか?私はそこからいくつかのコードを取り、それが私の問題を部分的に説明していたので(起動するためのきちんとした図で)。

于 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 に答える