はじめに
こんにちは、新卒2年目の岡崎です。今回はhx-trigger
を使ってinfinitScrollを実装する方法を紹介します。
環境
- gradle
------------------------------------------------------------ Gradle 8.5 ------------------------------------------------------------ Build time: 2023-11-29 14:08:57 UTC Revision: 28aca86a7180baa17117e0e5ba01d8ea9feca598 Kotlin: 1.9.20 Groovy: 3.0.17 Ant: Apache Ant(TM) version 1.10.13 compiled on January 4 2023 JVM: 21.0.2 (Amazon.com Inc. 21.0.2+13-LTS) OS: Mac OS X 12.3 aarch64
openjdk version "21.0.2" 2024-01-16 LTS OpenJDK Runtime Environment Corretto-21.0.2.13.1 (build 21.0.2+13-LTS) OpenJDK 64-Bit Server VM Corretto-21.0.2.13.1 (build 21.0.2+13-LTS, mixed mode, sharing)
- Spring Boot
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.2.1)
今回は、htmxを使っているため、以下の依存関係をbuild.gradle
に追加します。
implementation "org.webjars.npm:htmx.org:1.9.10"
実装
hx-trigger
を使うことで、infinitScrollを簡単に実装できます。
hx-trigger
の詳細は、公式ドキュメントをご覧ください。
Controller
まずは、Controllerにエンドポイントのを作成します。
/scroll
は、最初にアクセスした際の画面表示用エンドポイントです。/scroll/new
は、スクロール時に呼び出されるエンドポイントです。
@Controller @RequestMapping("scroll") public class ScrollController { @GetMapping public String get( Model model ) { final List<String> list = List.of( "test1", "test2", "test3", "test4", "test5", "test6", "test7", "test8", "test9", "test10" ); model.addAttribute("list", list); return "scroll/index"; } @GetMapping("new") public String getNew(Model model) { final List<String> list = List.of( "newTest1", "newTest2", "newTest3", "newTest4", "newTest5", "newTest6", "newTest7", "newTest8", "newTest9", "newTest10" ); model.addAttribute("list", list); try { Thread.sleep(3000); } catch (InterruptedException e) { throw new RuntimeException(e); } return "scroll/index :: scroll"; } }
html
- scroll/layout.html
レイアウトファイルを作成しました。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" lang="ja" th:fragment="layout(content)" > <head> <title>Demo</title> <script src="/webjars/htmx.org/1.9.10/dist/htmx.min.js"></script> </head> <body> <header> header </header> <div th:replace="${content}"> <p>Page content goes here</p> </div> <footer> footer </footer> </body> </html>
- scroll/index.html
画面にlistの内容を表示します。
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" lang="ja" th:replace="~{scroll/layout::layout(~{::content})}"> <body> <th:block th:fragment="content"> <th:block th:insert="~{scroll/index::scroll}"></th:block> </th:block> <th:block th:fragment="scroll"> <div class="container text-center mt-5"> <th:block th:each="row : ${list}"> <div th:text="${row}"></div> </th:block> </div> <div> <span hx-indicator="#indicator" hx-target="closest div" hx-trigger="revealed" hx-swap="outerHTML" th:hx-get="@{/scroll/new}"> Loading...... </span> </div> </th:block> </body> </html>
下記の部分がスクロール部分の実装です。
<span hx-target="closest div" hx-trigger="revealed" hx-indicator="#indicator" hx-swap="outerHTML" th:hx-get="@{/scroll/new}"> Loading...... </span>
今回は、スクロール時にリクエストを発火させたいので、hx-trigger
に revealed
を指定しました。これにより、指定された div タグがスクロールで表示されると、/scroll/new
が呼び出されます。
また、hx-indicator="#indicator"
を使用してローディング処理を実装しました。
最後に、スクロール時の挙動を確認できたら、完了です。
最後に
今回はhx-trigger
を使ってinfinitScrollを実装する方法を紹介しました。みなさんもぜひ実装してみてください。