Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Site list scrolls to top on every delete — fixing the missing keepScroll argument across 6 call sites

2026年08月22日に「Dev.to」が公開したITニュース「Site list scrolls to top on every delete — fixing the missing keepScroll argument across 6 call sites」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

サイトリストで項目削除などの操作をすると、ページが常に最上部に移動してしまう不具合があった。これは、スクロール位置を保持する「keepScroll」という引数を関数呼び出し時に渡していなかったのが原因だ。引数を明示的に渡すよう6箇所のコードを修正し、操作後もスクロール位置が保持されるようになった。

ITニュース解説

システム開発において、ユーザーがアプリケーションを快適に利用できるよう、細部にわたる配慮が求められる。今回取り上げるのは、一見些細に見えるが、ユーザー体験に大きく影響するスクロール挙動に関する修正事例である。WordPress Maintenance Managerというシステムで、ユーザーがサイトのリストを操作する際に発生していた不便な現象と、その原因、そしてどのように解決されたのかを詳しく見ていこう。

このシステムでは、管理しているサイトの一覧が表示されていた。ここで特定のサイトを削除したり、リストの並び順を変えたり、あるいはバックグラウンドで何らかのデータが更新されたりすると、画面が自動的に一番上までスクロールしてしまうという問題が発生していた。想像してみてほしい。数百ものサイトがリストアップされている中で、真ん中あたりのサイトを削除したとする。すると画面が一番上に戻ってしまうため、続けて別のサイトを操作したい場合、ユーザーは毎回手動でリストをスクロールし直して、目的の場所まで移動しなければならなかった。これは非常に手間がかかる作業であり、特に頻繁にリストを操作するユーザーにとっては大きなストレスとなっていた。

このような現象は、サイトの削除時だけでなく、ドラッグ&ドロップによるサイトの並べ替え後、リストのサムネイル画像が取得された後(この処理は画面には直接見えない部分、いわゆる「モーダル」の裏側で動いていた)、カテゴリの削除後、タグの削除後、そしてメンテナンス作業が完了した後など、合計6つの異なる操作で確認されていた。いずれの操作も、リストのデータが更新されるタイミングで発生していた共通点がある。

この不便な挙動の根本的な原因は、システムのコードの中にある特定の関数の使い方に問題があったことにあった。fetchSites() という関数は、サイトのリストデータをサーバーから取得し、その結果に基づいて画面上のリストを更新する役割を担っていた。この fetchSites() 関数は、keepPagekeepScroll という二つの「引数」を受け取るように設計されていた。引数とは、関数が処理を実行するために必要となる情報のことである。

特に重要なのが keepScroll 引数だった。この引数に true という値が渡されると、画面上のリストが更新された際でも、現在のスクロール位置をそのまま維持するように、という指示がシステムに送られる。具体的には、画面を一番上までスクロールさせるための window.scrollTo({top: 0}) という命令が実行されなくなる仕組みが組み込まれていたのだ。このスクロール位置を保持するメカニズム自体は、v1.6.6というバージョンで既に実装されており、正しく動作するはずだった。

しかし、問題は、前述の6つの操作で fetchSites() 関数が呼び出される際に、この keepScroll 引数が「省略されていた」ことにあった。関数の定義では、keepScroll 引数が省略された場合に自動的に適用される「デフォルト値」として false が設定されていた。つまり、引数を明示的に指定しないと、常に keepScroll=false として関数が実行されてしまう構造になっていたのである。

結果として、リストが更新されるたびに keepScrollfalse と判断され、画面を一番上まで強制的にスクロールさせる処理が毎回実行されてしまっていたのだ。修正前のコードでは fetchSites(true) のように記述されていたが、これは keepScroll が省略されたことで fetchSites(true, false) と同じ意味になってしまっていた。これを、keepScroll 引数を明示的に true と指定する fetchSites(true, true) という形に修正することで、問題は解決された。

具体的には、サイトの削除処理、ドラッグ&ドロップによる並べ替え完了時の処理、サムネイル取得後の処理、カテゴリ削除処理、タグ削除処理、そしてメンテナンス完了後の処理の、合計6か所のコードが修正された。それぞれの箇所で、fetchSites(true) と書かれていた部分を fetchSites(true, true) へと変更したのである。

特に興味深いのが、サムネイル画像の取得ケースである。この処理は、ユーザーが直接見ている画面ではなく、裏側でデータが更新されるため、ユーザーには何が原因で画面がスクロールしたのかが全く分からず、不審に感じるケースが多かった。また、メンテナンス完了のケースでは、作業中に画面をスクロールさせない別の仕組みがすでに存在していたにもかかわらず、作業完了後の最終的なリスト更新でスクロールが発生してしまい、一貫性のない挙動になっていた点もこの修正によって改善された。

ただし、例外として、システムが最初に起動してサイトリストを読み込む際の fetchSites() 呼び出しは、意図的に修正されていない。アプリケーションの初回ロード時には、ページが一番上、つまりスクロール位置が0にリセットされるのが正しい挙動とされているため、この場合はスクロール位置を保持する必要がないからである。

この事例から私たちが学ぶべき重要な教訓がいくつかある。この問題は、既存の「スクロール位置を保持する」という機能自体が壊れていたわけではない。そうではなく、後から追加された新しい操作を実装する際に、既存の fetchSites() 関数を呼び出す際に、その関数が提供する引数(今回の場合は keepScroll)の使い方や、他の場所での呼び出し方を十分に確認しなかったことが原因であった。

新しい機能を開発する際、既存の関数を利用する場面では、その関数がどのような引数を受け取り、それぞれの引数がどのような意味を持つのか、そして他の場所でどのように使われているのかをしっかりと確認する習慣をつけることが極めて重要である。このような確認を怠ると、今回のように、機能自体は存在していても、その機能が正しく活用されずにユーザーに不便を強いる結果を招いてしまうことがある。これは、開発者がコードを書く際に「当たり前」と感じるような、基本的ながらも非常に大切な心構えである。既存のコードを尊重し、その使い方を学ぶことで、より堅牢でユーザーフレンドリーなシステムを構築できるようになる。

関連コンテンツ

関連ITニュース