どうもこんばんは!HYPのこうじです。
今回は縦に長いページでページ内移動が便利になる『一番上に戻るボタン』の実装をしようと思います!
- は?iphoneは上の方タップすれば一番上いくから要らないっしょ。
- パソコンは”Home”ボタン使いなYO!
(ちなみにかなこさんは僕と同様、自分にとって必要なモノ以外覚えないので実際にこういう発言はしません。多分…)
まぁこんな事いったら元も子も無いですが、全ての人が知っているわけではないので、視覚的直観的に『あぁこれ押すと上まで行くんだろうな』というのが分かるボタンがあると非常に親切というのもあります。
この記事の内容
一番上に戻るボタンの実装
htmlタグの作成
まずはこれが無いと元も子もありません。
ボタンのサイズ自体は、今回動的に動かす予定はないので、アローにはsvgを利用します。
svgは画像と違って別途ファイルを用意する必要がない上、iphoneにありがちな画像サイズが足りなくて画質が劣化…なんて事もないので非常に便利!
ただ、古いInternet ExploreやAndoroidブラウザーでは表示に違い出る恐れがあります。
これを</body>の直前に置きます。
<div id="move_to_top"> <a href="#wrap"> <!-- <body id="wrap">になっている前提でページ内移動をしています。--> <svg id="svg-move_to_top" data-name="MoveToTop" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 14"> <title>一番上に戻るボタン</title> <polyline points="2 12 13 2 24 12" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/> </svg> </a> </div>
デザインを作る
ボタンのデザインを作りましょう。
html同様サクッと作ります。
説明なし!待ったなし!
#move_to_top { position: fixed; bottom: -80px; right: 10px; z-index: 10; -webkit-transition: bottom, .2s, ease; transition: bottom, .2s, ease; } #move_to_top.show { bottom: 10px; } #move_to_top > a { display: block; width: 60px; height: 60px; background: #000; border-radius: 50%; text-indent: -999em; -webkit-transition: background-color, .2s, ease; transition: background-color, .2s, ease; } @media (min-width: 768px) { #move_to_top > a:hover { background-color: #333; } } @media (max-width: 767px) { #move_to_top > a { width: 50px; height: 50px; } } #move_to_top > a > svg { display: block; position: absolute; top: 50%; left: 50%; -webkit-transform: translate(-50%, -50%); transform: translate(-50%, -50%); -webkit-transition: top, .2s, ease; transition: top, .2s, ease; width: 30px; height: 16px; } @media (max-width: 767px) { #move_to_top > a > svg { width: 25px; height: 13.45px; } } @media (min-width: 768px) { #move_to_top > a:hover > svg { top: 40%; } }
常にボタンを表示させる場合は?
実は上のスタイルシートはある程度スクロールされたら上にボタンを表示という仕組みを前提としている為、最初の表示がされない設定になっています。
常に表示でいいよ!なんて人は、以下の部分を変更すれば常時表示されます。
#move_to_top { position: fixed; bottom: 10px; /* 80px => 10pxに変更 */ right: 10px; z-index: 10; -webkit-transition: all, .2s, ease; transition: all, .2s, ease; } /* この指定を削除。 */ #move_to_top.show { bottom: 10px; }
ある程度スクロールされたらボタンを表示するスクリプト
ここから本題。
一番上にある時に”一番上に戻るボタン”は必要ですか?
なんか会社勤め時に上司に皮肉たっぷりに言われそうな言葉を回避する為、ある程度スクロールされたら上にボタンを表示という仕組みにします。
Vanilla JS
// 上に戻るボタンの要素を取得。 var MTP = document.getElementById('move_to_top'); // 要素がある場合のみ処理するようにする。 if (MTP) { // スクロールされた場合に処理するイベントを登録。 window.addEventListener('scroll', function() { // ページのスクロール量でクラスを振り分ける。 if (window.pageYOffset > 1000) { // ページのスクロール量が1000pxを超えたら // ボタン要素に『show』クラスを追加。 MTP.classList.add('show'); } else { // それ以外の場合は『show』クラスを削除。 MTP.classList.remove('show'); } }); } // <head />内に記述等、上に戻るボタン要素よりも // 前に書きたい場合はイベントリスナーで囲む document.addEventListener('DOMContentLoaded', function() { // ここに上のスクリプトを記述。 });
jQuery
// 上に戻るボタンの要素を取得。 var $MTP = $('#move_to_top'); // 要素がある場合のみ処理するようにする。 if ($MTP.size() > 0) { // スクロールされた場合に処理するイベントを登録。 $(window).scroll(function() { // ページのスクロール量でクラスを振り分ける。 if ($(this).scrollTop() > 1000) { // ページのスクロール量が1000pxを超えたら // ボタン要素に『show』クラスを追加。 $MTP.addClass('show'); } else { // それ以外の場合は『show』クラスを削除。 $MTP.removeClass('show'); } }); } // <head />内に記述等、上に戻るボタン要素よりも // 前に書きたい場合はイベントリスナーで囲む $(function() { // ここに上のスクリプトを記述。 });
11行目にある数値『1000』を任意の数値に変えるとスクロール量による表示位置を変更出来ます。
ボタンの表示と非表示の動作は、全てスタイルシートで行っているので、スクロール量による変化はクラスを振るか降らないかの処理のみです。
余談ですが、昔はイージング処理(位置移動時のアニメーション)もjQueryの『animate』や『fadeIn』等を使わないと非常に大変でしたが、今はスタイルシートの『transition』を利用すれば動作も軽く、簡単に表現出来るので便利な世の中になりましたね!
ますますjQueryのありがたみが少なくなっていく気がします。
完成
お疲れさまでした!
仕上がりはこんな感じです。
See the Pen grGwYA by Kouji Hayashi (@Regless) on CodePen.0
なんかイージングしないですね。実際はしますよ!
[番外編] ボタンタグも自動で追加する
例えば全てのページに例外なく使用したい場合は<div id=”move_to_top” />部分もスクリプトにしてしまうのも有りです。
必要なくなったらスクリプトを変更するだけで全てのページから撤去出来ますし、変更もここ一つで済みます。
ただ、指定ページのみボタンを表示させると言った場合はタグでhtmlファイルに直接打ち込んだ方が無難です。
ボタンタグを自動にするには</body>直前にスクリプトを打ち込みます。
勿論イベントリスナを使って<head />内に入れても問題ありません。
その場合は、記述の順番に注意して下さい。
スクロール処理を書く前に下記のボタン追加スクリプトを書かないと正常に動作しません。
読み込み順についてはこちらの記事でも触れているので、合わせて見てみて下さい。
Vanilla JS
// ボタン要素を作成して追加。 var moveToTopBox = document.createElement('div'); moveToTopBox.id = 'move_to_top'; moveToTopBox.innerHTML = '<a href="#wrap">' + '<svg id="svg-move_to_top" data-name="MoveToTop" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 14">' + '<title>一番上に戻るボタン</title>' + '<polyline points="2 12 13 2 24 12" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>' + '</svg>' + ' </a>'; // body要素に追加。 document.getElementsByTagName('body')[0].appendChild(moveToTopBox);
jQuery
// body要素に追加。 $('body').append($( '<div id="move_to_top">' + '<a href="#wrap">' + '<svg id="svg-move_to_top" data-name="MoveToTop" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 14">' + '<title>一番上に戻るボタン</title>' + '<polyline points="2 12 13 2 24 12" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>' + '</svg>' + ' </a>' + ' </div>' ));
[番外編] ページ内移動をスムーズにスクロールする
今の状態だと、一番上に戻るボタンを押すと、パッと一番上に移動します。
そう、パッとね。
それをにゅるにゅる~っと上に移動したい場合には、外部のライブラリを利用すると便利です。
僕が良くお世話になっているライブラリはこれです。
このライブラリのいいトコロは、jQueryに依存しないで使う事が出来ます!
設置方法はコチラのサイトに非常に分かりやすく解説されていますので確認してみて下さい。
おわり
ECサイトの契約上で使用出来るサーバーはphpも使えない上、ポンパレモールに至ってはwebフォントすら使えない悲惨な状況なので、唯一残されたjavascriptを如何に上手く使うかでページのUI/UXは全然変わってくると思います。
限られた道具を効率的に使って、より良いページにしていきたいですね!
せめて楽天はスマホの商品ページのタグ制限が、フィーチャーフォンレベルなのをどうにかしろ。