今回はこのような疑問に答えていきます。
jQueryでappendやprependで要素を追加した後にスクロールさせない(要素に移動させない)方法
先日、メッセージの追加読み込み機能を開発していたところ、「さらに読み込むボタン」を押してprependで追加すると、追加した要素にスクロールで移動してしまいました。
そこで、移動させないようなコードを書いたので紹介します。
実際のコード
HTML側のコードとJS側のコードをそれぞれ紹介します。
なお、HTML側はすでに動的に要素が追加された後のものとします。
(rowというクラスの要素を追加したとします。)
↓HTML
HTML側<div class="message-container" style="overflow: auto; height:24rem;"> //ここからスクロール要素 <div class="message-area"> <div class="message-body" id="scroll-content"> <div class="message-bodey-buttuon"> <div class="more-read-button text-center"> <button id="more-read-button-1">さらに読み込む</button> </div> </div> <div class="all-content"> //動的に追加した部分 -- start -- <div class="row"> <span class="text-right block text-xs message-body-time">8:44</span> <span class="text-right block message-body-content" id="message-id-1">おはよう</span> </div> //動的に追加した部分 -- end -- <div class="row"> <span class="text-right block text-xs message-body-time">8:44</span> <span class="text-right block message-body-content" id="message-id-2">おはよよう</span> </div> <div class="row"> <span class="text-left block text-xs message-body-time">21:25</span> <span class="text-left block message-body-content" id="message-id-3">テスト</span> </div> </div> </div> </div> </div>
↓JS側
JS側const scrollToElm = $( `#message-id-2` ).parent().position().top; //all-contentからの距離を取得 const buttonHeight = $( ".all-content" ).position().top; //message-bodyからの距離を取得 const nowScrollHeight = $( ".message-container" ).scrollTop(); //現在のスクロールの距離を取得 $( ".message-container" ).scrollTop( scrollToElm - buttonHeight + nowScrollHeight ); //要素追加前の位置にスクロールを移動させる
実装のポイントをいくつか解説していきます。
ポイント①:スクロールさせない→元の位置までスクロールするという発想に転換
「要素追加時にスクロールさせたくない」という考えを「要素追加後に元の位置までスクロールする」という発想に転換しました。
先程のJSのコードの「$( ".message-container" ).scrollTop....」の部分です。
ちなみに、scrollTopは引数として、位置の値を渡すとその位置までスクロールしてくれます。
Description: Set the current vertical position of the scroll bar for each of the set of matched elements.
ポイント②:親要素からの距離をうまく算出して、スクロールさせたい距離を出す
position()メソッドを使って、親要素からの距離を算出して、スクロールさせる距離を取得しました。
後は先程のscrollTopに渡してあげればOKです。
Description: Get the current coordinates of the first element in the set of matched elements, relative to the offset parent.
移動した分をスクロールで戻してあげるイメージを持つと良い
「スクロールさせない」とかではなく、シンプルに、動的な要素追加のイベントで追加された要素の距離分をスクロールで戻してあげるイメージを持つと実装しやすいかなと思いました。
僕自身は、その考えに至るまで少しハマってしまったので...。
よかったら参考にしてみてください。
今回は以上です。