jQuery / ページ先頭へ滑らかに戻るリンクを作る
実際の目的地を持つhref="#top"を用意し、jQueryの.animate({ scrollTop: 0 })で文書のスクロール要素を動かします。即時のアンカージャンプは止めても、JavaScriptなしで使えるhrefは残します。動きを減らす設定では即時移動し、完了後に上部見出しへフォーカスします。
文書のスクロール要素と基本リンク
ページ全体の例です。document.scrollingElementは実際のスクロール要素を返し、標準モードなら文書ルートです。<!doctype html>を保ちます。一つを対象にすればhtml・body両方の効果や完了処理を扱わずに済みます。
先頭見出しにid="top"、リンクに対応hrefを設定します。tabindex="-1"は通常Tab順を増やさずコードでフォーカス可能にします。スクロールだけでは下部リンクにフォーカスが残るため別途移します。
一ファイルで動く完全な例
全コードをUTF-8のback-top-demo.htmlとして保存し、ブラウザーで開きます。インターネットで公式jQuery完全版4.0.0を読みます。時間付き効果はeffectsが必要でslimにはしません。サーバーやインストールは不要です。
Go to 900pxで比較位置を作り、右下リンクは常に使えます。短い文書では動かないため高さを確保しました。固定操作部は実習用で、実サイトはヘッダー・広告との重なりを避けます。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Smooth back-to-top link</title>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<style>
html { scroll-behavior: auto; }
body { font: 16px/1.6 sans-serif; margin: 0; padding: 100px 20px; min-height: 2400px; box-sizing: border-box; }
#top { max-width: 760px; margin: 0; }
#top:focus { outline: 3px solid teal; }
#toolbar { position: fixed; top: 0; left: 0; right: 0; background: #fff; padding: 12px; z-index: 2; }
button, a { font: inherit; }
button { margin: 4px; }
#back { position: fixed; right: 16px; bottom: 16px; padding: 10px 14px; background: #075d55; color: #fff; border-radius: 6px; z-index: 2; }
#status { position: fixed; left: 12px; bottom: 70px; max-width: calc(100% - 48px); padding: 8px; background: #fff; white-space: pre-wrap; overflow-wrap: anywhere; }
.spacer { margin-top: 700px; }
</style>
</head>
<body>
<div id="toolbar"><button type="button" id="down">Go to 900px</button><button type="button" id="stop">Stop movement</button></div>
<h1 id="top" tabindex="-1">Top of the example page</h1>
<p>Use the fixed link after scrolling down.</p>
<p class="spacer">Middle of the page</p>
<p class="spacer">Lower content</p>
<a id="back" href="#top">Back to top</a>
<pre id="status" aria-live="polite"></pre>
<script>
$(function () {
const root = document.scrollingElement;
if (!root) return;
const $root = $(root);
let completed = 0, state = "ready";
function report() { $("#status").text(`scrollY=${Math.round(window.scrollY)}\ncompleted=${completed}\nstate=${state}`); }
function interrupt() {
if (state !== "moving") return;
$root.stop(true, false); state = "interrupted"; report();
}
$("#back").on("click.backTopLesson", function (event) {
event.preventDefault();
$root.stop(true, false);
state = "moving"; report();
const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
$root.animate({ scrollTop: 0 }, { duration: reduce ? 0 : 600, complete: function () {
completed++; state = "done";
document.getElementById("top").focus({ preventScroll: true });
report();
} });
});
$("#down").on("click", function () { $root.stop(true, false).scrollTop(900); completed = 0; state = "ready"; report(); });
$("#stop").on("click", interrupt);
$(window).on("scroll.backTopLesson", report);
$(window).on("wheel.backTopLesson touchstart.backTopLesson", interrupt);
$(document).on("keydown.backTopLesson", function (event) {
if (["ArrowUp", "ArrowDown", "PageUp", "PageDown", "Home", "End", " "].includes(event.key)) interrupt();
});
report();
});
</script>
</body>
</html>
先頭の初期結果です。丸めは表示用で、計算を整数に限定しません。
scrollY=0
completed=0
state=ready
- Go to 900pxを押します。高すぎる画面で900に届かなければ高さを小さくします。
- Back to topは通常600msで戻り、途中値を経てscrollY=0、completed=1、state=doneです。
- 見出しにフォーカス枠が現れます。下リンクをフォーカスしてEnterでも確認します。
- 900から連打しても移動を積み上げず、前効果を止め現在位置から再開します。
- Stop movementは途中で止まりstate=interruptedです。再開はリンク、比較位置の復元はGo to 900pxです。
操作、キーボード、連打、中断、動きを減らす設定を3.7.1・4.0.0とWindows Edgeで実行しました。JavaScript無効でも#topへの基本リンクを確認しました。
連打・中断・動きを減らす設定
.animate()のscrollTopは数値0です。event.preventDefault()なしでは標準ジャンプと競合します。.stop(true, false)は待機を消し、到着点へ強制完了せず停止します。現在位置から再開でき、旧完了処理を実行しません。
ホイール、タッチ開始、スクロール用キーはinterrupt()を呼びユーザーへ操作を戻します。ユーザー操作をpreventDefaultで止めません。Stopも同じ関数です。中断なら見出しへフォーカスを強制しません。
prefers-reduced-motionを操作ごとに読み、不要な動きを減らす設定なら時間0にし、同じ完了経路でフォーカスします。全体のjQuery効果設定は変更しません。
focus({ preventScroll: true })はフォーカスによる二度目の位置変更を防ぎます。絶対先頭以外なら固定ヘッダーや目的地の座標を別途計算します。idだけ変えて全目的地に対応するわけではありません。
既存サイトへ適用する確認
既存id="top"を確認し目的地を一致させます。他の処理やCSSを上書きしない範囲の選択子・名前空間を使います。実習用900px操作、出力、人工的な文書高は実サイトに不要です。
同じ移動へCSS scroll-behavior:smoothとjQueryを重ねません。例はautoで時間をjQueryが管理します。不要ならネイティブwindow.scrollTo()のsmoothも選べますが、完了とフォーカスはその方法に合わせます。
動かなければ文書の余裕、内部コンテナー配置、完全版読込を確認します。説明文・コントラスト・モバイル操作領域・固定要素の重なりも見ます。JavaScript失敗時も使えるhrefを残し、javascript:や空住所にしません。




