ScrollIntoView()により、ページ全体が移動します


109

ScrollIntoView()を使用して、リストで強調表示されたアイテムをスクロールして表示します。下にスクロールすると、ScrollIntoView(false)は完全に機能します。しかし、上方向にスクロールすると、ScrollIntoView(true)によってページ全体が少し移動し、意図したとおりに移動します。ScrollIntoView(true)を使用するときにページ全体が移動しないようにする方法はありますか?

これが私のページの構造です-

#listOfDivs {
  position:fixed;
  top:100px;
  width: 300px;
  height: 300px;
  overflow-y: scroll;
}

<div="container">
    <div="content"> 
         <div id="listOfDivs"> 
             <div id="item1"> </div>
             <div id="item2"> </div>
             <div id="itemn"> </div>
         </div>
    </div>
</div>

listOfDivsはajax呼び出しからのものです。モバイルサファリの使用。

よろしくお願いします!


1
問題が何であるかを正確に確認できるように、JSFiddleを提供できますか?
Robert Koritnik

回答:


115

scrollTop代わりに使用できますscrollIntoView()

var target = document.getElementById("target");
target.parentNode.scrollTop = target.offsetTop;

jsFiddle:http ://jsfiddle.net/LEqjm/

スクロールするスクロール可能な要素が複数ある場合は、介在する要素のsにscrollTop基づいて、それぞれoffsetTopの要素を個別に変更する必要があります。これにより、発生している問題を回避するためのきめ細かい制御が可能になります。

編集:offsetTopは、必ずしも親要素に対して相対的であるとは限りません-最初に配置された祖先に対して相対的です。親要素が配置されていない場合(相対、絶対、または固定)、2行目を次のように変更する必要がある場合があります。

target.parentNode.scrollTop = target.offsetTop - target.parentNode.offsetTop;

3
参考までに、これは親がページの上部にいる場合にのみ機能します。あなたはおそらくそれを作るべきですtarget.parentNode.scrollTop = target.offsetTop - target.parentNode.offsetTop
Phil

2
offsetTopは、最も近くに配置された親を基準にしているため、親ノードにがある場合はposition: relative、そのオフセットを減算しないでください。しかし、ほとんどの場合、あなたは正しい。
ブリリアント

2
これがjs fiddleです:jsfiddle.net/LEqjm/258は、ScrollIntoViewの不適切な動作も示しています。
Rafi

1
@Brilliand position: relativeはprent div についてのアイデアをありがとう:それは本当に問題を修正します
Alex Zhukovskiy

それはクロムに取り組んでいますが、IEでは少しスクロールし、テキストコンテンツを上から隠しています。すべてのソリューション@Phil、事前に感謝
Soniya

120

それを修正しました:

element.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' })

参照:https : //developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView


1
これはうまくいきました。ブロックの使い方を理解できず、読んだときの値です。問題が解決したので、何をしているのかわかっています
Pavan

3
「最も近い」とはどういう意味ですか?編集:ここで答えを見つけました:stackoverflow.com/a/48635751/628418
Sammi

これで私の問題は解決しました。私はこれが私たちのWebアプリでしばらく発生するのを見てきましたが、その再現をロックダウンするのは困難です。新しい機能を追加した後、それは毎回発生し、block : 'nearest'param が欠落していたこの呼び出しまでたどることができました。
roskelld

彼らがブロックの値の意味を定義した場合にのみ...開始して最も近い...そのすべての試行錯誤。
Bae

Chromeでは機能しますが、Edgeでは機能しません。
マイケル


9

私もこの問題を抱えており、それに対処するために何時間も費やしました。私の決議がまだ一部の人々の役に立つことを願っています。

私の修正は結局:

  • Chromeの場合:(@jfrohnに感謝)に変更.scrollIntoView().scrollIntoView({block: 'nearest'})ます。
  • Firefoxの場合:overflow: -moz-hidden-unscrollable;シフトするコンテナー要素に適用します。
  • 他のブラウザではテストされていません。

8

遊んでscrollIntoViewIfNeeded()...ていることを確認し、それがブラウザでサポートされています。


1
それが事だったことを知りませんでした。ポリフィル
mpen

ドキュメントでは、それは標準ではないがそれはうまく機能しているとそこで言及されました。それを使うべきでしょうか?
Shyam Kumar

8

ScrollIntoViewの重要な動作を表示する方法を追加しました-http : //jsfiddle.net/LEqjm/258/ [コメントのはずですが、十分な評判がありません]

$("ul").click(function() {
    var target = document.getElementById("target");
if ($('#scrollTop').attr('checked')) {
    target.parentNode.scrollTop = target.offsetTop;    
} else {
        target.scrollIntoView(!0);
}
});

7
jQueryの質問ではありません。
18

6

jQueryプラグインscrollintoview()が使いやすさを向上

デフォルトのDOM実装の代わりに、動きをアニメーション化し、不要な影響を与えないプラグインを使用できます。デフォルトで使用する最も簡単な方法は次のとおりです。

$("yourTargetLiSelector").scrollintoview();

とにかく、すべての詳細を読むことができ、最終的にGitHubのソースコードにアクセスできるこのブログ投稿に向かいます。にはプラグインのに。

このプラグインは、最も近いスクロール可能な祖先要素を自動的に検索し、スクロールして、選択した要素が表示されているビューポート内に収まるようにします。要素がすでにビューポートにある場合は、もちろん何もしません。


19
@ブリリアン:もちろんそれは本当ですが、それが彼らがそれを使用していない、またはそれを使用することに消極的であるという意味ではありません。私がしているのは、代替手段を提供することだけです。それが彼らが取る道であるかどうかを決定するのはOPです。おそらく、そもそもjQueryの使用を検討したことがなかったのかもしれません。
Robert Koritnik 2012年

そのOPはjQueryがまったく無関係であることを具体的に言及していませんでした。@ RobertKoritnikの回答は私に完全に役立ちました。
デイ

1
ちなみに、Bingは「先祖要素がscrollintoviewでスクロールしないようにする」の検索結果にコードサンプルを表示しています。:-)
デイ

2

Brilliantのアイデアを使用して、要素が現在表示されていない場合にのみ(垂直に)スクロールするソリューションを次に示します。アイデアは、ビューポートの境界ボックスとブラウザウィンドウの座標空間に表示される要素を取得することです。要素が表示されているかどうかを確認し、表示されていない場合は、必要な距離だけスクロールして、要素がビューポートの上部または下部に表示されるようにします。

    function ensure_visible(element_id)
    {
        // adjust these two to match your HTML hierarchy
        var element_to_show  = document.getElementById(element_id);
        var scrolling_parent = element_to_show.parentElement;

        var top = parseInt(scrolling_parent.getBoundingClientRect().top);
        var bot = parseInt(scrolling_parent.getBoundingClientRect().bottom);

        var now_top = parseInt(element_to_show.getBoundingClientRect().top);
        var now_bot = parseInt(element_to_show.getBoundingClientRect().bottom);

        // console.log("Element: "+now_top+";"+(now_bot)+" Viewport:"+top+";"+(bot) );

        var scroll_by = 0;
        if(now_top < top)
            scroll_by = -(top - now_top);
        else if(now_bot > bot)
            scroll_by = now_bot - bot;
        if(scroll_by != 0)
        {
            scrolling_parent.scrollTop += scroll_by; // tr.offsetTop;
        }
    }

2

@Jesco投稿する情報を追加しています。

  • Element.scrollIntoViewIfNeeded() non-standard WebKit methodChrome、Opera、Safariブラウザ用。
    要素がすでにブラウザウィンドウの表示領域内にある場合、スクロールは行われません
  • Element.scrollIntoView() メソッドは、それが呼び出された要素をブラウザウィンドウの表示領域にスクロールします。

mozilla.org scrollIntoView()リンクで以下のコードを試してください。ブラウザを識別するための投稿

var xpath = '//*[@id="Notes"]';
ScrollToElement(xpath);

function ScrollToElement(xpath) {
    var ele = $x(xpath)[0];
    console.log( ele );

    var isChrome = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime);
    if (isChrome) { // Chrome
        ele.scrollIntoViewIfNeeded();
    } else {
        var inlineCenter = { behavior: 'smooth', block: 'center', inline: 'start' };
        ele.scrollIntoView(inlineCenter);
    }
}

2

私のコンテキストでは、彼は粘着性のあるツールバーを画面から押し出すか、絶対ボタンを使用してファブボタンの隣に移動します。

最も近い解決済みを使用します。

const element = this.element.nativeElement;
const table = element.querySelector('.table-container');
table.scrollIntoView({
  behavior: 'smooth', block: 'nearest'
});

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.