【@WIKI】アットウィキでページの先頭に戻るボタン(ページトップボタン)を設置する!

【@WIKI】アットウィキでページの先頭に戻るボタン(ページトップボタン)を設置する!

私はやりたい事ばかり多くて、アレもコレもと気が散ってイケナイ。
どれも( ゚д゚)ハッ!と思った時にちょこっとずつ調べたりメモったりなので、デスクトップは付箋アプリの付箋だらけ(しかもこの付箋アプリはテキストの検索機能がないので厄介だ。そのうち自作するか・・・ってまたやりたい事が増える)。
多分に加齢のせいもあるが、酒の毒がいよいよ30年殺しぐらいの勢いで元々足りない脳ミソを蝕んでいるらしく、アル中ハイマー記憶障害をたびたび発生させている。と言うワケで、忘れないウチにブログに書いて置こう。誰かの役に立つかも知れん。

※2019/08/09追記
ボタンの画像は違うが、PukiWikiで本稿と同様にページトップボタンを実装する記事を書いており、実際の動きを見ることが出来るので次のサイトで動作を確認されたい。

商用ウィキサービスのもどかしさ

長くなるから割愛するが、国内でも商用ウィキサービス(私は人間が古いので「Wiki」の方がピッタリ来るが「ウィキ」に統一)が定着しつつあり、利用する人も増えた。ウィキページを作ったり更新したりする人達が増えれば、それだけウィキ本来のナレッジベースとしての利用とその発展が望めるだろうから、単純に喜ばしいことだ。問題は大いにあるにせよ、誰しもウィキペディアのお世話になったことがあると思うし、今やウィキは大小様々な個人や組織に利用されているのである(と思う)。
中でも私は個人的にアットウィキが気に入っているのだが、他のブログサービス同様、商用サービスは自分で手が出せない(プログラムの追加・修正が出来ない)のがもどかしい。そこで私は個人的に長年趣味で集めた大・松本零士コレクションを自分でウィキ化しようとして、昨年夏ごろから自前レンタルサーバでPukiWikiを立てるべくカスタマイズをしていたが、冒頭のようにアレもコレもな状態で放置状態である。それでPukiWikiの改造記事を書き連ねているのだが。

それとはまた全然別件でアットウィキでサイトを運用して更新しているが、特にウィキページは情報が集まれば集まるほどページ当たりの情報量が増えるので長くなるし、ページの分割化による情報の分断もイヤなモンだ。少しでも使い勝手を良くするために、ページの先頭に戻るボタン(以降、「ページトップボタン」と統一)をアットウィキで実現することにした。

HTMLとJavaScriptだけで実現するぞ!

アットウィキは従来のウィキ記法の他に独自で拡張したプラグインが利用可能で、ウィキの簡単さ+プラグインの中途半端な高機能が微妙に心地良い(褒めてます)。現状スマホは「SP」が付くURLになるものの、レスポンシブに対応したCSSデザインも出たし、サポートに質問を投げても割とレスポンスが良い。日々バージョンアップしていて(だから突然仕様変更が入ってビビるが)今後も伸びて行きそうな気がする(気のせい?)。
正直、ウェブ系の技術は多岐に渡っていて、元々それが本職ではないせいもあるが、「今のご時世、jQueryで何とでもなるだろ」と気軽に考えていたが、所詮はやっぱりウィキなので、アットウィキではjQueryが利用出来ないようだ(プラグインで何とかなるかにゃ~?と淡い期待をしていたのだが)。
でもまぁ、単純にJavaScriptで window.scrollTo(0, 0); と書けば有無を言わさずページのトップにスクロールするのだから、アットウィキでHTMLとJavaScriptのコードが書ければjQueryが使えないからと言って諦める必要はない。
アットウィキのプラグインを色々と探してみると、

  • #html2():HTMLをそのまま表示(複数行入力対応)(html2)
  • #javascript():javascript入力プラグイン(javascript, js)

を使えば、jQueryを使わずにページトップボタンの実装が出来そうだ。

アットウィキにページトップボタン画像を仕込む

商用サービスの場合でも、ブログならFontAwesome(フォントオーサム)を利用してお手軽かつ楽ちんに様々なアイコン画像が使えるが、商用ウィキサービスではその仕様の特性上、HTMLの <head> <body> タグに<script>タグを仕込めないため、ページトップボタンの画像を用意してウィキページに仕込むしかない。

私は先日WordPress用プラグインでページトップボタンをお手軽に導入したので、そのプラグインが提供しているアイコンから使えそうなヤツを見繕った。

やはり「コレだ!」というモノがないので、運用しているウィキサイトのイメージに合うように加工してこんなボタン画像を用意した。

page-top-button.png
縦横64ピクセル

どうやってこのボタン画像をアットウィキに仕込むか?だが、ウィキではページに画像を添付するのはワケない話なので、メニューページに添付して仕込めば良いだろう。

メニューページを編集する画面に移動してこのように画像ファイルを添付すれば良い。アットウィキは複数のファイルを添付する場合でもドラッグ&ドロップで簡単に追加出来るので楽だ。

ボタン画像をアップロードしたら、ファイル名のリンクを右クリックして「リンクのURLをコピー」するのも忘れずに。このURLを使ってHTMLコードでページトップボタンに仕立てるからだ。

JavaScriptファイルの作成

JavaScriptのコードは.jsファイルにまとめておき、それをメンテナンスする方が圧倒的に保守性も上がるし効率が良い。ページトップボタンと同様にメニューページに仕込んでおき、任意のウィキページから参照出来るようにすれば良いだろう。
そこで、次のコードを「page-top-button.js」ファイルとして作成する。短いコードなのでテキストエディタでコーディングしたが、念のため文字コードを「UTF-8」にして保存する。

page-top-button.js

                                        // ページトップボタンをセット
var topButton = document.getElementById('page-top-button');
                                        // イベント登録
// ボタンクリック
topButton.onclick = function() {
    scrollToTop();
};
                                        // スクロール量の取得
function getScrolled() {
    return (window.pageYOffset !== undefined) ? window.pageYOffset: document.documentElement.scrollTop;
};
                                        // ページトップボタンの表示・非表示
window.onscroll = function() {
    (getScrolled() > 50) ? topButton.classList.add('fadeIn'): topButton.classList.remove('fadeIn');
};
                                        // ページトップ移動関数
function scrollToTop() {
    var scrolled = getScrolled();
    window.scrollTo(0, Math.floor(scrolled / 2) );
    if (scrolled > 0) {
        window.setTimeout(scrollToTop, 30);
    }
};

いざ、実装!

ウィキとは言えJavaScriptを使うので、アットウィキの場合はページの編集権限を「管理者のみ」に設定しないと、せっかくのJavaScriptが有効にならない

アットウィキのプルダウンメニュー「編集」→「ページの閲覧/編集権限の変更」をクリックし、ページトップボタンを設置するページは全て図のように編集権限を変更する必要がある。
私が運用しているウィキサイトは私しかページの作成も編集もしないから良いが、不特定多数または複数の参加者とウィキの編集をしているサイトの場合は、かなり切実な問題ではある。ページトップボタンの導入ごときでウィキサイトの運用に支障をきたすのは、普通にダメだろう。
ともあれページの編集権限を変更したら、編集するページの一番最後にコピペすればOK!(ページを編集・保存する前に、管理者設定からCSSを先に追加して設定を保存しておく必要はあるが

任意のウィキページに次のコードをコピーペーストする

----
#html2(pc){
<img id="pageTopButton" src="https://img.atwikiimg.com/www99.atwiki.jp/hogehoge/attach/2/53/page-top-button.png">
}

#javascript(){
<script type="text/javascript" src="https://img.atwikiimg.com/www99.atwiki.jp/hogehoge/attach/2/54/page-top-button.js"></script>
}

CSSは(管理者でログイン→「設定」→「デザイン」→「CSSカスタマイズ」)次のコードをコピーペーストして保存する。

#page-top-button {
    position: fixed;                    /* 固定表示 */
    right: 20px;                        /* 右から20ピクセル(任意の位置に設定) */
    bottom: 60px;                       /* 下から60ピクセル(任意の位置に設定)*/
    transition: opacity 1s;             /* 透過変化時間(1秒) */
    opacity: 0;                         /* 透過(非表示) */
}

#page-top-button.fadeIn {
    position: fixed;                    /* 固定表示 */
    display: block;                     /* ブロック表示 */
    right: 20px;                        /* 右から20ピクセル(任意の位置に設定) */
    bottom: 60px;                       /* 下から60ピクセル(任意の位置に設定)*/
    outline-style: none;                /* アウトライン非表示 */
    box-shadow: none;                   /* 影表示なし */
    cursor: pointer;                    /* ポインタカーソル設定 */
    z-index: 9999;                      /* Zオーダで最上位に設定 */
    transition: opacity 1s;             /* 透過変化時間(1秒) */
    opacity: 0.8;                       /* 非透過80% */
}

#page-top-button.fadeIn:hover {
    transition: opacity 1ms;            /* 透過変化時間(0.001秒) */
    opacity: 1;                         /* 非透過100% */
}

コードの解説

簡単ではあるが、コードの解説をしよう。

ウィキページのコード

 

#html2(pc){
<img id="pageTopButton" src="https://img.atwikiimg.com/www99.atwiki.jp/hogehoge/attach/2/53/page-top-button.png">
}

#javascript(){
<script type="text/javascript" src="https://img.atwikiimg.com/www99.atwiki.jp/hogehoge/attach/2/54/page-top-button.js"></script>
}

#html2()プラグインは特に説明することはないが、私が運用しているウィキサイトはレスポンシブ対応前のCSSデザインのため、スマホではURLに「SP」が付くせいか、スマホ画面では標準でページトップボタンが表示される。よって、プラグインの引数に「pc」を追加して「パソコン」(タブレットでも同様)のみの出力にしている。
<img> タグでメニューページで添付したページトップボタン画像を定義し、これを#javascript()プラグインで同じくメニューに添付した「page-top-button.js」ファイルのJavaScriptとCSSで制御する。

CSS

 

#page-top-button {
    position: fixed;                    /* 固定表示 */
    right: 20px;                        /* 右から20ピクセル(任意の位置に設定) */
    bottom: 60px;                       /* 下から60ピクセル(任意の位置に設定)*/
    transition: opacity 1s;             /* 透過変化時間(1秒) */
    opacity: 0;                         /* 透過(非表示) */
}

#page-top-button.fadeIn {
    position: fixed;                    /* 固定表示 */
    display: block;                     /* ブロック表示 */
    right: 20px;                        /* 右から20ピクセル(任意の位置に設定) */
    bottom: 60px;                       /* 下から60ピクセル(任意の位置に設定)*/
    outline-style: none;                /* アウトライン非表示 */
    box-shadow: none;                   /* 影表示なし */
    cursor: pointer;                    /* ポインタカーソル設定 */
    z-index: 9999;                      /* Zオーダで最上位に設定 */
    transition: opacity 1s;             /* 透過変化時間(1秒) */
    opacity: 0.8;                       /* 非透過80% */
}

#page-top-button.fadeIn:hover {
    transition: opacity 1ms;            /* 透過変化時間(0.001秒) */
    opacity: 1;                         /* 非透過100% */
}

ボタンの表示(フェードイン効果)と非表示(フェードアウト効果)はCSSで実装し、JavaScriptで fadeIn 要素をクラスに追加(表示)・削除(非表示)で実現している。ボタンの表示は1秒かけてボタンを80%の透過度で表示し、同様に1秒かけてボタンを80%の透過度から0にして非表示にしている。これにより、フェードイン効果とフェードアウト効果(簡単なアニメーション)を実現している。また、マウスがボタンに 重なった時(Hover時)は1ミリ秒でサッと100%表示にしている。マウスがボタンから離れた時は100%から80%の透過度に戻るが、この時に1秒かかるのは「ロジック的に」私には解決出来なかった。
ともあれ、取り敢えずウィキページにコードを貼る形で実現するのでボタンが派手に下や右から登場はしないものの、CSSは効果的かつ最低限でシンプルなものとした。

スクロール量の取得

スクロール量を取得するJavaScriptを調べるといくつかあるが、ブラウザによって対応状況が違うので困った。

  • window.pageYOffset⇒IEは非対応(undeinedを返す)
  • document.body.scrollTop⇒ForeFoxだと戻り値が0?
  • document.documentElement.scrollTop⇒ChromeとSafariの対応が怪しい

結局、「IEに対応しとく?」って話になるんだが、捨てるよりは・・・という判断でこのようなコードになった。多分、この判断は間違いではないだろうし、今回スマホは考えなくて良いが、スマホでもこのコードで大丈夫だろう。

                                        // スクロール量の取得
function getScrolled() {
    return (window.pageYOffset !== undefined) ? window.pageYOffset: document.documentElement.scrollTop;
};

ページトップボタンの表示・非表示

 

                                        // ページトップボタンをセット
var topButton = document.getElementById('page-top-button');

                                        // ページトップボタンの表示・非表示
window.onscroll = function() {
    (getScrolled() > 50) ? topButton.classList.add('fadeIn'): topButton.classList.remove('fadeIn');
};

CSSの箇所でも書いたが、スクロール量が50ピクセルを超えたら fadeIn 要素をクラスに追加するか削除するかで表示と非表示を実現している。
私は「少しでもスクロールしたらすぐ反応させたい」人なので50ピクセルとしたが、この辺は本当にお好みで。

ページトップ移動関数

 

                                        // ページトップ移動関数
function scrollToTop() {
    var scrolled = getScrolled();
    window.scrollTo(0, Math.floor(scrolled / 2) );
    if (scrolled > 0) {
        window.setTimeout(scrollToTop, 30);
    }
};

単純にページのトップに移動するだけなら、 window.scrollTo(0, 0); とすれば良い。ただこれだと一瞬で移動するため、ぶっちゃけ面白くないし素っ気なさ過ぎる
そこで、クイックソートのように取得したスクロール量の半分まで移動して30ミリ秒(0.03秒)デレーし、スクロールイベントの発生で取得したスクロール量の半分まで移動してデレーし・・・と自動的にスクロールイベントが繰り返されて行けば、スクロールする移動量と移動にかかる時間が徐々に【速い(移動量・多)→遅い(移動量・少)】に変化し、見た目は「スーッ」となめらかにスクロールしてページのトップに移動するような効果が得られる
終了条件はスクロール量が【0=ページトップ】になるまで勝手に【スクロール→イベント発生→スクロール】を繰り返すので、短いコードで最大の効果が得られる

おわりに

ウィキ記法そのものは実にシンプルなので、誰でもすぐに習熟してページの作成や更新が簡単かつ手軽に行えるため、ナレッジベースとしてウィキは優れていると思う。しかし、1ページ当たりの情報量が増えて行った場合に「見やすく」「便利に」といった面では、ウィキサイトの機能の拡張を行わなくては対応が取れないのも事実である。
私の場合は商用ウィキサービスを利用するに当たって、一通り見た中でアットウィキが気に入って使っているから、正直他社のウィキサービスの「本当の良さ」は分からないし、アットウィキも含め、商用サービス各社も日々改良をし続けていることだろう。
私が運用しているウィキサイトは更新・管理が私一人だし、管理しているページ数もまだ少ないから、アットウィキの仕様的な制限の中で今回のページトップボタンの設置を実施出来た。しかし、不特定多数や複数人でページの作成や更新をしているサイトや、ページ数が数百ページ以上にものぼるようなサイトだと実質導入は無理か、相当に厳しいと思われる。
ウィキの利用と普及がまだまだだと言ってしまえばそれまでではあるし、サービスを提供しているアットウィキ側を責められない面もあるが、何でスマホだけ標準でページトップボタンが用意されているのかそれをPCやタブレットユーザに何故開放しないのか?と疑問に思わざるを得ない。

 

 

この記事が気に入ったら
いいね ! をお願いします


ソフトウェアカテゴリの最新記事