本文
自分のウェブサイトでうつ病チェックを作っていて、結果表示ボタンが押された際に未記入の項目を検知し、その位置までスクロールするようにする機能を追加しようと考えていた。
自分のWebサイトのうつ病チェック
スクロール機能を実装する際、以下の記事を参考にjQueryで書いてみた。
const jump = curSheet.findIndex(e => e === -1);
var target = $(`#question_${jump}`);
var position = target.offset().top-70
var speed = 500;
$("html, body").animate({scrollTop:position}, speed, "swing");
return false;
これをchatGPTに書き換えてもらった。
// curSheet 配列から -1 のインデックスを取得
const jump = curSheet.findIndex(e => e === -1);
// 対象の要素を取得
const target = document.getElementById(`question_${jump}`);
// 対象の位置を取得(70px のオフセットを引く)
const position = target.getBoundingClientRect().top + window.pageYOffset - 70;
// スクロールの速度を設定
const speed = 500;
// スムーズスクロールを実行
window.scrollTo({
top: position,
behavior: 'smooth'
});
// スクロールが完了する前にページが遷移するのを防ぐ
return false;
ありがたいことに解説つきでコードが出てきた。
Web制作初心者なので、scrollTo
の存在をここで初めて知った。この方法ではどうやらspeed
は設定できないらしい。スムーズスクロールの方法を調べていたが、jQueryやCSSを用いた方法ばかりが出てきてこの方法は見つけられなかった(CSSを用いた方法は、ページ内リンクをクリックしたときのスクロールだったので今回必要なものではないと思われる)。これに関しては多分自分の調べ方が悪い。
70pxのオフセットを引いているのは、引かないとスクロールした際にターゲットがヘッダーの下に埋もれてしまうためである。
出てきたコードを修正すると以下のようになった。
// curSheet 配列から -1 のインデックスを取得
const jump = curSheet.indexOf(-1);
// 対象の要素を取得
const target = document.getElementById(`question_${jump}`);
// 対象の位置を取得(70px のオフセットを引く)
const position = target.getBoundingClientRect().top + window.scrollY - 70;
// スムーズスクロールを実行
window.scrollTo({
top: position,
behavior: 'smooth'
});
// スクロールが完了する前にページが遷移するのを防ぐ
return false;
findIndex
をindexOf
に変えたのと、pageYOffset
をscrollY
に変更した。speed
は削除した。
スムーズスクロールは基本この方法で簡単にできるが、もしもっと良い方法があればコメントで教えていただきたい。
追記
return false
ではなくevent.preventDefault()
のほうがいいらしい。
また、調べていたらこのような記事を見つけた。
window.requestAnimationFrame()
という関数を利用し、ディスプレイのリフレッシュレートに合わせてスクロールを行っている。もし複雑なアニメーションを実行したいならこの方法が有効と思われる。