はてなブログでページ内スムーズスクロールを実現させる
これはもう言わずもがなのjQueryを使ったテクニックですが、はてなブログには「はてな記法モード」という編集モードがあって、その編集モードの場合、リンクの記述にちょっと注意が必要になるので、あえてエントリ記事を作成しました。
やっていることは、他たくさんのブログで紹介されているjQueryのロジックと同じなので、その説明はほとんどなしで、あくまでも「はてな記法モード」での記述の仕方がメインです。
jQueryの説明
以下のjQuery(javascript)を、はてなブログの設定画面の「デザイン」→「カスタマイズ」タブ→「ヘッダ」→「タイトル下」(HTMLを記述できます)へ、コピペしてください。既にscript定義があれば、その中にマージしてもいいです。
※ちなみに、はてなブログではjQueryがデフォルトで使えるので、script文でsrc指定してjquery.jsを定義しなくともいいんですよ。
<script> //ページ内スムーズスクロール移動 $(function(){ $('a[href^=#]').click(function(){ var speed = 500; var href= $(this).attr("href"); var target = $(href == "#" || href == "" ? 'html' : href); var position = target.offset().top - 40; $("html, body").animate({scrollTop:position}, speed, "swing"); return false; }); }); </script>
#13/7/11追記:はてなブログのデザインテーマ(#globalheaderの有無)によって、「position = target.offset().top - 40;」の行の「40]という値を変更する必要があることがわかりました。これが合ってないと、飛び先の位置が微妙にずれます。なので、このjQueryを適用する場合は適宜この数値の調整をお願いします。
「はてな記法モード」時のページ内移動の指定の仕方
このjQueryを使う場合は、リンク先のタグ要素にid指定し、リンク元はaタグのhrefでid指定してやればいいのですが
「はてな記法モード」の場合は、本来のはてな記法独自のリンクの書き方が出来なく、普通にaタグを書く必要があるので、そこが注意点です。
リンク先側の記述の仕方
「はてな記法モード」では直接HTML記述も出来るので、以下のように指定してやります。
<span id="jump">リンク先はここです</span>
リンク先はここです
あるいは、飛び先が大見出し(h3タグ)でも良ければ、こういう書き方も出来ます。
*jump*リンク先はここです
リンク元の記述の仕方
はてな記法の場合、リンクは本来は独自の書き方をするのですが、それをid名に置き換えただけではリンクにならないので、aタグを直接記述する必要があります。
以下のように記述してもリンクになってくれません。
[#jump:title=「リンク先はここです」へ移動]
こんな感じ↓でそのまま表示されるだけで、リンクにならない
[#jump:title=「リンク先はここです」へ移動]
なので、以下のように普通にaタグを記述する必要があります。
<a href="#jump">「リンク先はここです」へ移動</a> <a href="#main">エントリー記事トップへ移動</a>
「リンク先はここです」へ移動
エントリー記事トップへ移動 ※この#mainは最初からエントリー記事の先頭に定義されているid名です。
【関連記事】
- はてなブログでトップ位置固定のメニューを作成する
- はてなブログで位置固定のページトップボタンを設置する
- はてなブログのカテゴリ記事数によって、カテゴリ文字の大きさを変化させる
- はてなブログデザインテーマのCSS変更点を紹介するよ
- 「プログラミング」カテゴリ一覧へ
【タグ】
{jQuery}
はてなブログでトップ位置固定のメニューを作成する
まず最初にお断りです。
これを実装するにはCSSやHTMLについて、そこそこの知識が必要です。
一番の注意点としてあげられるのは、はてなブログにはブログ最上部にグローバルヘッダ(DIV#globalheader-container)という、「Hatena Blog」って左側に書いてあるメニューバーがあって、これがデザインテーマによってpositionプロパティの指定が違うんですよ。position static;だったり、position fixed;だったり。
#わかりやすく言えば、スクロールさせたときにそのメニューバーが画面の外に消えるか、そのまま残るかってこと。それによって当然TOPプロパティの値を変える必要がある。
ちなみにこのブログのトップ位置固定メニューだって、このデザインテーマだとちゃんと表示されていますが、試しに他のデザインテーマに変えてみると、テーマによってはまともに表示されないものもあります。
全てはデザインテーマのCSS設定が違うことにあるんですね。
メニューの幅もエントリ領域(DIV#container)のmerginプロパティの値によってwidthプロパティの調整が必要だったり、単にコピペしただけではまともに表示されない可能性の方が高いです。
「メニューが片方に偏って表示される」「画面からはみ出してしまう」「スクロールさせたときに固定されず画面の外に出てしまう」など、いろいろ問題点が出てくると思うので、はっきりいって難易度は高いです。
あとこのメニューをちゃんと表示させるために「既存のcss設定値もいじることになる」場合もあるので、注意しないと元に戻せなくなる可能性もあります。
とにかく自分が満足できるようになるまでに、かなり手間がかかることは覚悟してください。
実はこのエントリ記事は、ずっと前にできてたんだけど、そういった理由もあって公開すべきかどうか迷ってたんだよね。
以前、紹介したはてなブログで位置固定のページトップボタンを設置するや、はてなブログのカテゴリ記事数によって、カテゴリ文字の大きさを変化させるみたいに、コピペすれば動くってものじゃなかったから。
だから「転んでも泣かない」っていう人じゃないとお勧めできないので注意してください。ここ重要なのでしっかり覚えておいてくださいね。
言い忘れてましたが、これの元ネタは「Webpark - ウェブサイト作成に役立つことをいろいろと」というブログを参考にさせてもらっています。このブログさんにはいろいろなcssテクニックが紹介されてて、しかも懇切丁寧な説明つきなのですごく参考になります。ぜひ訪れてみてください。
※注意:IEしか使ったことがない方はわからないと思いますが、他のモダンブラウザだとドロップダウンのサブメニューが、するっするっと降りてくる(言い方難しいな。なんて表現すればいいのだろう?)のですが、IEだとCSSのtransitionプロパティが効かないので、そのメニューが一瞬で表示されてしまいます。
このtransition効果の動きは自分は結構気に入っているのですが、IEだとそれをお見せできないのが非常に残念です。
HTMLの設定
ここからは上記で詳細させていただいたブログさんの2つのエントリ記事を組み合わせて作成しています。
・ドロップダウンメニュー作成時の参考リンク:CSSだけで作る動きのあるドロップダウンメニュー
→こちらが今回主に参考にしたリンク先です。
・位置固定メニュー作成時の参考リンク:上部固定メニューのお供に、jQueryを使ったクリックで開閉するメニュー
→こちらはメニュー部分のHTMLを参考にさせてもらっただけで、他はほとんど流用していません。
自分がオリジナルからいじったところは、はてなブログには「#globalheader-container」があるため、固定メニューのHTMLに加えjavascript(jQuery)を追加したところが大きな違いです。あとは色の指定など細かい部分だけで、その他はほとんど変わっていないので、詳細な説明はぜひ上記のリンク先を参照していただければ、と思います。
自分のヘボい説明(汗)より、ずっとずっとわかりやすい説明が載っています。
では、まずメニュー部分のhtmlとトップ位置固定するためのjavascript(jQuery)の全文です。
メニュー部分は各自変更してください。
これらを「デザイン」→「カスタマイズ」タブ→「ヘッダ」→「タイトル下」(HTMLを記述できます)へ、コピペしてください。
メニューカスタマイズの際の注意点としては、
- 子メニューの最後に「メニューを閉じる」をいうのを追加していますが、これはiPad対策のためです。iPadだとCSSのhover擬似クラスが効かなく、メニューをタップした後メニューが開きっぱなしになってしまうので、強制的にトップページを表示させることによってメニューを消してるという苦肉の策です。
- はてなブログの場合はたぶんないとは思いますが、もしかするとブログのhtmlソース上に#globalheader-containerがないものがあるかもしれません。その場合はglobalheaderPosition=0とデフォ設定した方がいいかも。その辺りは適宜判断してください。
- メニュー部分のHTMLを作る時の参考として、何でしたらこのブログのHTMLソースを見てもらえれば、より具体的な設定の仕方がわかってもらえると思います。
<div id="fixed-menu" class="absoltop"> <div id="fixed-menu-contents"> <ul id="dropmenu"> <li><a href="URL1">メニュータイトル1</a></li> <li><a href="URL2">メニュータイトル2</a></li> <li><a href="URL3">メニュータイトル3</a></li> <li><a href="#">メニュータイトル4</a> <ul> <li><a href="子URL1">子メニュー1</a></li> <li><a href="子URL2">子メニュー2</a></li> ・ ・ <li><a href="topページurl">メニューを閉じる</a></li> </ul> </li> <li><a href="#">メニュータイトル5</a> <ul> <li><a href="子URL1">子メニュー1</a></li> <li><a href="子URL2">子メニュー2</a></li> ・ ・ <li><a href="topページurl">メニューを閉じる</a></li> </ul> </li> </ul> </div> </div> <script> $(function() { var fixedmenu = $("#fixed-menu"); var fixedmenuTop = fixedmenu.offset().top; // 画面スクロール毎に判定を行う $(window).scroll(function() { //もし#globalheader-containerが存在しない場合は、以下3行を削除してglobalheaderPositionに0をデフォ設定してください。 var globalheadercontainer = $("#globalheader-container"); var globalheaderPosition = globalheadercontainer.offset().top; var globalheaderheight = globalheadercontainer.height() - 1; //#globalheader-containerのpositionプロパティ判定 static or fixed。 if (globalheaderPosition == 0) { // #globalheader-containerがposition: staticの場合 if ($(window).scrollTop() >= fixedmenuTop) { fixedmenu.addClass("fixedtop0"); } else { fixedmenu.removeClass("fixedtop0"); } } else { //#globalheader-containerがposition: fixedの場合 if ($(window).scrollTop() >= fixedmenuTop - globalheaderheight) { fixedmenu.addClass("fixedtop"); } else { fixedmenu.removeClass("fixedtop"); } } }); }); </script>
jQuery部分の補足説明
この部分は、はてなブログならではのオリジナルなので、説明を加えておきます。
ここでやっていることは3つです。
- #globalheader-container の位置取得(= globalheaderPosition変数)
- globalheaderPosition変数の値が、0ならstatic(固定なし)、1以上になればfixed(位置固定)と判断
- staticならばTOPプロパティに0pxを設定したクラス(fixedtop0)を、fixedならばTOPプロパティには37px(#globalheader-containerの高さ分)を設定したクラス(fixedtop)を、スクロールに合わせて追加したり、削除したりする(この「クラスの追加、削除」というのは、こういう位置固定手段の際のお約束のロジックですね)
使っているテーマの#globalheader-containerがstaticなのか、fixedなのか最初からわかっていれば、このif文は削除して片方のロジックだけにしてもらっても構いません。汎用性を持たせるためにこのif文を入れただけなので。
CSSの設定
次は「デザインCSS」の設定で、CSS定義のどこでもいいんですが以下をコピペしてください。
くれぐれも他のCSS定義は消さないようにね!
/* Top Menu */ #fixed-menu { width: 100%; max-width: 940px; padding: 0; z-index: 9999; /* background: #2e4153;*/ } .absoltop { position: absolute; top: 37px; } .fixedtop { position: fixed; top: 37px; } .fixedtop0 { position: fixed; top: 0px; } #dropmenu { list-style-type: none; width: 100%; height: 30px; margin: 0 auto 0 0; padding: 0; background: #56b5f0; border-bottom: 3px solid #0a4970; } #dropmenu li { position: relative; width: 20%; float: left; margin: 0; padding: 0; text-align: center; z-index: 9999; } #dropmenu li a { display: block; margin: 0; padding: 5px 0 11px; color: #fff; font-size: 16px; font-weight: bold; line-height: 1; text-decoration: none; } #dropmenu li:hover > a{ background: #1490dd; /* color: #a4d7f7; */ color: #ff0000; } #dropmenu > li:hover > a{ border-radius: 5px 5px 0 0; } #dropmenu li ul { position: absolute; top: 100%; left: 0; list-style: none; margin: 0; padding: 0; border-radius: 0 0 3px 3px; } #dropmenu li:last-child ul { left: -100%; width: 100% } #dropmenu li ul li { overflow: hidden; width: 200%; height: 0; color: #fff; -moz-transition: .2s; -webkit-transition: .2s; -o-transition: .2s; -ms-transition: .2s; transition: .2s; } #dropmenu li ul li a{ padding: 13px 15px; background: #1490dd; text-align: left; font-size: 16px; font-weight: normal; } #dropmenu li:hover ul li{ overflow: visible; height: 38px; border-top: 1px solid #56b5f0; -moz-transition: .4s ease .5s; -webkit-transition: .4s ease .5s; -o-transition: .4s ease .5s; -ms-transition: .4s ease .5s; transition: .4s ease .5s; border-bottom: 1px solid #616d0b; } #dropmenu li:hover ul li:first-child{ border-top: 0; } #dropmenu li:hover ul li:last-child{ border-bottom: 0; } #dropmenu li:hover ul li:last-child a{ border-radius: 0 0 5px 5px; }
CSSの補足説明
.absoltop { position: absolute; top: 37px; } .fixedtop { position: fixed; top: 37px; } .fixedtop0 { position: fixed; top: 0px; }
ここが、jQueryのロジックに関連して必要となったもので、オリジナルで追加した部分です。
デフォルトでは、#fixed-menuには、absoltopクラスが設定されていますが、jQueryによってスクロール位置を判断し、fixedtopクラスとfixedtop0クラスを使い分けて、追加したり、削除したりするのに使っています。
ちなみにわざわざabsoltopクラスを作っているのには理由があります。それは、はてなブログではHTMLを記述できる箇所が限定されているからなんですね。
試しに#fixed-menuからabsoltopクラスを削除してメニューを表示させると、そのメニューは「ブログタイトルの下」に表示されてしまいます。これはやってもらうとわかります。だからこのabsoltopクラスの指定が必要なのでした。
最後に
基本的には、メニュー部分さえちゃんと作ってしまえば、後は位置調整のためにpx指定をいじるくらいだとは思うのですが、最初にも書いたとおりCSS設定がデザインテーマによってまったく違うので、まずこれをコピペしてみて、まともに表示されればラッキー。
もしまともに表示されなければ、間違いなく既存のCSS設定値をいじる必要があって、しかもそれはデザインテーマによって、いじらなければならないところがまちまち。
どのプロパティをいじらなければならないのか?それをどうやってそれを調べるのか?など、問題は山積みだと思います。
#だから、コピペだけで動かなかったとして「どこが悪いんでしょうか?」という問い合わせをいただいたとしても、こちらとしてはそのデザインテーマのCSS設定値がわからないので、お答えしようがないのです・・・。かなり無責任な発言になってしまいますが、ご了承ください。
なので、ここから先はその人次第です。
「CSSなんてちょろいよ?」という方ならご自分のブログ用に余裕でカスタマイズできると思いますが、「CSSって何?」ってレベルだと、正直お勧めできません。
だから、いざというときに元に戻せるという自信がなければ、全部削除して諦めるか、
これも勉強のうちと思ってチャレンジするか。
自分は一応後者の方だったので、これを実装するには何度も試行錯誤を繰り返して、結構大変な思いをしました。
でもその甲斐あって満足できるものができましたけども。
自分もCSSのことはこのブログを始めるまでマジで知識0でしたけど、いろいろいじっているうちにだんだん理解できるようになったんですよね。
そうなると、やっぱりめちゃ楽しくなるんですよ。
自分が使っているデザインテーマで不満なところがあった場合に、どこを改善すればいいのかわかるようになるんだもの。
このメニューを作ったときにも新たなCSSの勉強もできたし、そうやって覚えたことを元にして、このデザインテーマをいろいろカスタマイズしてます。
#ちなみに、そのカスタマイズ内容も、後日別エントリ記事としてアップしようと思っています。
この固定メニューにチャレンジすることは、CSSを覚えるいい機会だと思うんですよね。
ぜひがんばってもらって、CSSに関する知識の量を増やしていただきたいな、と思っています。
【関連記事】
- 「プログラミング」カテゴリ一覧へ
【タグ】
{html}{css}
はてなブログで位置固定のページトップボタンを設置する
ページスクロールに関係なく位置が固定された「ページトップへ戻る」ボタン。
このネタもぜひ実装したかったんですよね。
普通だと、最後までスクロールしてやっと「ページトップへ戻る」ボタンがあるじゃないですか。でも、そこに行くまでにトップへ戻りたい場合って意外と多いから、この機能ってなんで標準装備じゃないんだろうっていつも思う(まぁ、ブラウザによって挙動が違ったりするかもしれないので難しいのだろうけど)
実はこれもtmd45さんのサイトからいただいたネタなんですが、ただこちらは自分がtmd45さんのブログページソースを見させてもらって勝手に拝借(つまりパクった)ので、もしまずかったらごめんなさい。
改めて紹介しますが、元ネタは
はてなブログ サイドバーのカテゴリ表示をタグクラウドにする! - TMD45INC!!!
#13/5/26追記:上記記事が改良(よりわかりやすく)されました。タグクラウド化に興味のある方はこちらへ
【改訂版】はてなブログ サイドバーのカテゴリ表示をタグクラウドにする! - TMD45INC!!!
です。
それでは本題です。
HTMLモジュールの配置
まず設定箇所ははてなブログのカテゴリ記事数によって、カテゴリ文字の大きさを変化させるで紹介したとおり、サイドバーのhtmlモジュールとして配置してください。
<p id="page-top"><b><a href="#PAGETOP">↑ページトップへ</a></b></p> <script> // ページトップへ移動ボタンの表示 $(function() { var topBtn = $('#page-top'); topBtn.hide(); $(window).scroll(function () { if ($(this).scrollTop() > 100) { topBtn.fadeIn(); } else { topBtn.fadeOut(); } }); //スクロールしてトップ topBtn.click(function () { $('body,html').animate({ scrollTop: 0 }, 500); return false; }); }); </script>
補足
もし、前回紹介した「カテゴリ名の大きさを変える」HTMLモジュールと共存させたい場合、サイドバーにそれぞれのHTMLモジュール配置してもいいですけど、上記スクリプトにマージしちゃう手もあります。
その場合は、前回のスクリプトの
最初の1行 script 行と、最後の1行 /script 行の2行を削除して、
上記スクリプトの最後の行 /script 行の前にコピペしてください。
CSSの設定
次は「デザインCSS」の設定で、CSS定義のどこでもいいんですが以下をコピペしてください。
くれぐれも他のCSS定義は消さないようにね!
/* ページトップへ移動 */ #page-top { position: fixed; bottom: 30px; right: 0; } #page-top a { background: rgba(153,204,255,.6); text-decoration: none; color: #fff; padding: 15px 30px 15px 15px; border-radius: 10px; } #page-top a:hover { background: rgb(0,153,255); border-radius: 10px; }
ちなみにオリジナルと違って、ボタンの色は自分の好みで青系に変えてます。
ボタンの色を変えたい場合はCSSを教えているホームページを見たりしてbackground文の値を変更してください。
最後に
tmd45さんのボタンの良いところは、普段は邪魔にならない程度に半透明で、マウスオンしたときにだけ色が濃くなるところですね。さすがtmd45さんのセンスです。
【関連記事】
- 「プログラミング」カテゴリ一覧へ
【タグ】
{html}{css}
はてなブログのカテゴリ記事数によって、カテゴリ文字の大きさを変化させる
記事数が多いカテゴリ名の大きさを自動で変化させるスクリプトです。
自分も一応技術屋の端くれなので、たまにはこんなネタを提供したいと思います。
まず、このネタは
はてなブログ サイドバーのカテゴリ表示をタグクラウドにする! - TMD45INC!!!
#13/5/26追記:上記記事が改良(よりわかりやすく)されました。タグクラウド化に興味のある方はこちらへ
【改訂版】はてなブログ サイドバーのカテゴリ表示をタグクラウドにする! - TMD45INC!!!
から、ヒントを得て改造したものです。
これによって実装できたときは、tmd45さんにコメントでお礼を伝えたかったのですが、コメントできないブログ(13/5/16追記:自分がDISQUSのjavascriptを禁止してたからコメントできなかっただけでした。コメントでお礼をさせていただきました)だったので、申し訳ございませんがこんな場所でお礼を述べさせてください。
すごく助かりました。ありがとうございました。
改造要件
自分の場合は、カテゴリの記事数に応じてカテゴリ名の大きさを変化させる、という他に、
- 基本的にカテゴリの記事数は表示させる
- ただし、メインカテゴリ名となる「x00番のカテゴリ」には件数を表示させず、大きさも変更対象外とする
としたかったので、その辺をいじってます。
#13/5/18追記:以下のスクリプトには反映していない*1ですが、カテゴリ名から数字を削除する変更を入れました。
HTMLモジュールの配置
まず、ブログのダッシュボードの「デザイン」から
「カスタマイズ」→「サイドバー」→「+モジュールを追加」→「HTML」で
以下のスクリプトをコピペしてください。
<script> $(function() { //original written by id:tmd45 //improved by id:BNorider //カテゴリの記事数に応じて、カテゴリ名の大きさを変える var categories = $(".hatena-module-category ul li a"); $.each( categories, function(index, domEle) { var ele = $(domEle); var texts = $.trim(ele.text()); //original // リンクテキストから記事件数を取得 //original var count1 = texts.match(/\([^\(\s +]+\)/); //original var count2 = count1[0].match(/\d+/); // カテゴリNo.x00の場合は大きさ変更対象外とする if(texts.match(/^\d(00)/) != null){ var count2 = 0; } else { var count1 = texts.match(/\([^\(\s +]+\)/); var count2 = count1[0].match(/\d+/); } // 大きさ指定 Start if(count2 >= 10) ele.css("font-size", "230%"); else if(count2 >= 7) ele.css("font-size", "200%"); else if(count2 >= 5) ele.css("font-size", "170%"); else if(count2 >= 3) ele.css("font-size", "150%"); else if(count2 >= 2) ele.css("font-size", "120%"); else ele.css("font-size", "90%"); // 大きさ指定 End //original // リンクテキストから記事件数を除去 //original ele.text(texts.replace(/\([^\(\s +]+\)/, '')); // カテゴリNo.x00のみリンクテキストから記事件数を除去 if(count2 == 0){ ele.text(texts.replace(/\([^\(\s +]+\)/, '')); } // ツールチップに記事件数含めて表示する(title要素) ele.attr("title", texts); } ); }); </script>
※細かいところですが、記事数による変更箇所も増やしてます。この辺りは、各自お好みで。
※あと、たぶん他の方はカテゴリ名の頭にx00なんて数字をつけていないと思うので、ここら辺のロジックは削除しなくても問題ないです。
最後に
改造、再配布、全て自由で構いませんが、オリジナルはあくまでもtmd45さんなので、自分よりもtmd45さんに感謝してあげてくださいね。
【関連記事】
- 「プログラミング」カテゴリ一覧へ
【タグ】
{html}
*1:だって、他の人はカテゴリ名に数字なんていれていないよね。でも、もし知りたい場合は、このページのページソースを見てみてください