Hatena::ブログ(Diary)

KAZUMiX memo

2008-04-18

こだわりのページ内リンクスムーズスクロール scrollsmoothly.js

| こだわりのページ内リンクスムーズスクロール scrollsmoothly.jsを含むブックマーク

こだわりのページ内リンクスムーズスクロール scrollsmoothly.js 動作サンプル

「ページ内リンク スムーズスクロール」でググればいくらでも出てくるシロモノだけど、自分の要望をすべて満たすものが無かったので作ってみた。

以下のソースコードをサンプルページのようにhead内で読み込むだけでOK。

ソースコード(Javascript)
scrollsmoothly.js

読み込み例

<script type="text/javascript" src="scrollsmoothly.js"></script>

特徴

  • 縦横斜めにスクロール可能
  • スクロール中にもリンクをクリック可能
  • 別のページからのリンクでも指定の場所までスムーズスクロールします
  • MIT License

動作確認ブラウザ

関連エントリー

umeume 2008/06/29 00:38 素晴らしいスクリプトを公開していただき、ありがとうございます。
これを利用させていただくことにより、問題が解決しました。
今後のご活躍をお祈り申し上げます。

KAZUMiXKAZUMiX 2008/06/30 14:05 umeさん
どもです。このスクリプトは動きの気持ちよさにもこだわってみました。

☆ 2008/07/18 18:09 すごいですね!気持ちいい!
何より他のライブラリに依存していないところが素晴らしいです。

拝借して色々実験していたのですが、
「別のページからのリンクでのスクロール」が
一旦、そのアンカー部分を表示した後で、
また一番上からスクロールし直すという挙動のようですね。
(スクロール動作までの時間を弄んでいて気づいた)
これだとなんかスクロールする意味が希薄かもしれませんね…。

<a href=”ホニャララ.html#ホゲホゲ”>のそもそもの動作を
捻じ曲げるわけですから、やっぱり難しいのかな…。

KAZUMiXKAZUMiX 2008/07/18 20:03 そうなんですよね。ご指摘の通り、特にページが読み込み終わるまでに時間がかかる場合の挙動はいまいちかもしれません。でも読み込み終わらないとスクロール先の座標が確定できないので悩ましいところです。
そもそもの挙動をのっとるのは難しくてひとまず諦めました。何か方法が見つかれば何とかしたいです。

はまちゃんはまちゃん 2008/09/06 11:33 これはすごいですね。
他のものもいろいろ試しましたが、動きがなんとといっても1番気持ちいいですね。

少し初歩的な質問なのですが、よろしいでしょうか。
JavaScriptコード内の、
(function(){
var easing = 0.25;
var interval = 20;   
の部分なのですが、

他のブラウザはこのままでいいけれど、
例えば、ある特定のブラウザに対してだけその数値を変えたかったとすると、どういったコードの表記になるのでしょうか。

初歩的な質問で恐縮ですが、どうかよろしくお願いします。

ukeuke 2008/09/12 10:31 頂きました!ありがとうございます。
ビールの一箱でも贈呈したいくらいです。
こういう無償で活動されている方にお礼をしたい場合は
どうしたら良いのか社内のプログラマに聞いた所
「神!」と呼べば良いと言われました。。

ありがとうございます神様。

CHODACHODA 2008/10/21 16:29 動きのスムーズさとHTMLに実装したときのソースの簡素さが理想的!!
ライセンスはいかがいたしましょうか・・。

KAZUMiXKAZUMiX 2008/10/21 23:51 あ、ライセンスはMITです。ソースの中に書いておいたんですが、表にも書いておかないと分かりにくいですね。

CHODACHODA 2008/10/22 09:30 コードの中ちゃんと見てなかったです。。すみません。
活用させていただきます!

cagecage 2008/11/21 13:08 十字キーで移動出来ないですかね?

KAZUMiXKAZUMiX 2008/11/22 18:29 できません。
スライドショー的なページならそういうインターフェースも有りですね。

mitomito 2008/12/12 17:32 これはいいですね!
ひとつだけ、、
飛び先のアンカーが文書の最下部に近いと、イーズアウトされないのが残念。

KAZUMiXKAZUMiX 2008/12/12 20:31 確かに!
飛び先が表示の先頭になることを前提に座標の処理をしていたので、改良の余地有りですね。

ハルハル 2009/01/13 20:14 滑らかな動きで凄く気持ちいいですね!
早速実装してみたのですが、
flash上のボタンからだとスクロールせずに、
通常のアンカーのようになるのですが、
スルスルっと動かすにはどうすればよいでしょうか?

KAZUMiXKAZUMiX 2009/01/13 22:48 残念ながらFlashからのリンクには対応できません。このスクリプトはHTLM内のリンク動作をJSで乗っ取ることで実現していためです。
やろうとするとFlashからJavaScriptを呼び出し、JavaScript側もそれに対応するようにするかたちになります。埋め込んだだけで使えるこのスクリプトの仕様とは別物になってしまいます。

KAZUMiXKAZUMiX 2009/02/12 00:40 上記mitoさんのご指摘にあった「飛び先のアンカーが文書の最下部に近いと、イーズアウトされない」問題を修正しました。

HIHIHIHIHIHI 2009/04/09 19:03 スクロールしている途中で画面をクリック(またはマウスホイールを使用した際)した時はそこでストップするようにすることはできないものでしょうか?
スムーススクロール系で一番残念に思うのが強制的に飛び先までいってしまうものが多いのでぜひとも改良してください!!

まるまる 2009/10/14 18:05 これはいい! 使い勝手もよくて感動しました。

yukilinkyukilink 2010/01/31 08:54 はじめましてこんにちわ。
スムーズスクロール・・・いろいろ検索して試行錯誤して漂流してこちらにたどり着きました。
素敵です!!自分が理想としていたモノができそうです!!いや、できます!!
ありがとうございました。

じゃりおんじゃりおん 2010/02/27 21:02 とっても素敵なjsを、MITとはありがたいです。
今度の仕事のサイトで活用させていただきます。どうもありがとうございます!!

黒 2010/04/07 06:02 はじめまして。
サイト制作初心者なので初歩的な質問かもしれませんが、
「こだわりのページ内リンクスムーズスクロール scrollsmoothly.js 動作サンプル」
のソースを写して、勉強させてもらっているのですが、(悪魔で自分のPC内での使用ですが、もし違反行為でしたらすみません)
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
の部分を入れると文字化けになってしまうのですが、何故なのでしょうか?
「こだわりのページ内リンクスムーズスクロール scrollsmoothly.js 動作サンプル」のページを見ても文字化けしませんが、自分のPCに写して見ると文字化けしてしまいます。
それと<?xml version="1.0" encoding="utf-8"?>の記述が無いのも気になります。
変な質問ですが、どうかよろしくお願いします。

KAZUMiXKAZUMiX 2010/04/07 14:31 黒さん、はじめまして。
文字化けの原因は文字コードだと思います。元ソースの文字コードはutf-8ですが、保存した時にshift_jisになってしまったのではないでしょうか?
<?xml version="1.0" encoding="utf-8"?>の記述は、あえて入れていません。これを入れるとIE6が後方互換モード(IE5.5相当)の動作になってしまうためです。対策が面倒になるためため、私に限らず入れていないサイトがほとんどだと思います。

黒 2010/04/07 19:26 文字化けの原因はやはり保存した時に文字コードshift_jisで保存していたみたいです。
初歩的なミスで質問してしまって失礼しました。
<?xml version="1.0" encoding="utf-8"?>の記述は
<?php echo '<?xml version="1.0" encoding="utf-8"?>'; ?>で対処していますが、やはり入れないほうが良いのでしょうか?
連続的に質問してしまって申し訳ないですが、よろしくお願いします。

yoshiyoshi 2010/04/08 15:57 <a href="#">のように、「#」だけの場合スムーズスクロールになりません。
通常ブラウザの場合、「#」だけでページトップに移動します。
対応できませんか?m(_)m

KAZUMiXKAZUMiX 2010/04/09 10:56 >黒さん
IE6の場合は出力しないという分岐をしているのであれば問題ありません。そもそもIE6で正常表示されなくても気にしないというスタンスもありです。 Googleが今後はIE6のサポートををしないという立場のように。

>yoshiさん
今のところ空のアンカー名に対応する予定はありません。

JPJP 2010/07/27 06:17 はじめまして。とっても滑らかで気持ちがよいです。
初歩的な質問で恐縮ですが、質問させてください。
基本横だけにスクロールし、たまに注釈等のコンテンツを下などに配置したりするページ(基本は一方通行)をつくっているのですが、スクロール先の場所の指定はCSSのtopやleftのところで指定すればいいのですよね?セクション4の場所をセクション3の隣に書き変えてもデフォルトの1の下に移動してしまうのですが…
初心者の質問ですいません。よろしくお願いいたします。

KAZUMiXKAZUMiX 2010/07/28 17:41 >JPさん
スクロール先の指定はhtml内のidです。
CSSの方で見た目のレイアウトの指定をします。

nobitaniannobitanian 2010/08/04 01:19 初めまして。
とてもすてきなライブラリですね。
基本的な事を聞いて申し訳ありません。
scrollsmoothly.jsをダウンロードをしたいのですが、何処から
ダウンロードすることが出来るのですか?

mm 2010/10/22 14:36 はじめまして。
印刷がSection1しかできないのですがどうしたら、他のSectionも印刷できるようになりますか?

KAZUMiXKAZUMiX 2010/10/25 12:11 私のサンプルの場合ですと、印刷用に別のCSSを作る必要があります。

suzukisuzuki 2010/10/31 20:58 使わせていただいております。
大変すばらしいスクリプトをありがとうございます。
operaでは、斜め移動するときナビゲーションの部分がぶれるものが多かったので重宝しております。

2つ質問ですが、
ブラウザの「前へ戻る」ボタンを押下した場合、今まで表示させたSectionへ戻らせるのではなく、普通に前に表示させていたサイトに戻るようにすることは可能でしょうか?

また、ブラウザの「前へ戻る」ボタンを押下した場合、今まで表示させたSectionへ戻らないときが御座いますが改善する方法は御座いますでしょうか?

KAZUMiXKAZUMiX 2010/11/01 14:39 >suzukiさん
Sectionへ戻るのではなく、前のページへ戻るようにするのは簡単に対応できます。
124行目に以下の記述があります。
location.hash = targetHash;
これを削除すればOKです。

現状の前のSectionへ戻らないことがある挙動は確かに気持ち悪いですね。
すぐに対処法が思いつかないので、解決法を発見しだいなんとかしたいです。

ricyoricyo 2010/12/27 16:32 すばらしいスクリプトありがとうございます。
活用させていただいております。
さて、スクリプトの動きについてですが、

(function(){
var easing = 0.20;
var interval = 100;

このあたりの数字を変えれば動きがゆっくりになったり速くなったりするのはわかるのですが、動きに変化をつけるにはどうすればよいでしょうか?

たとえば、
はじめはゆっくりスタートして、途中は加速し、最後またゆっくり着地するようなイメージの動きが理想的です。

現在は、スタートが速く、最後がゆっくり着地するような感じになっています。

お忙しいとは存じますがご教授いただければ幸甚です。

KAZUMiXKAZUMiX 2010/12/27 17:57 このスクリプトの動きは、だんだん遅くなるイーズアウトと呼ばれる方法でアニメーションさせています。この部分ですね↓
var vx = (targetX - currentX) * easing;
var vy = (targetY - currentY) * easing;
var nextX = currentX + vx;
var nextY = currentY + vy;

逆に最初が遅いのがイーズイン。
で、このスクリプトはイーズアウトのことしか考えていないので、両方組み合わせるとなると少し面倒です。単純に両方を組み合わせるとなると、目標座標の半分まではイーズイン、半分から最後まではイーズアウトという風になります。
この辺、柔軟に対応するための方法や式などは「イージング」で調べるとといろいろありますので、がんばって改造してみて下さい。

kabkab 2011/05/19 22:59 とても素晴らしいスクリプトありがとうございます。
一つ質問してもよろしいでしょうか?
KAZUMiXのこだわりのページ内リンクで、それぞれのセクションでコンテンツを中心揃え(縦横共に)で配置したいと思っています。横はCSSで単純にできるのですが、縦で苦しんでいます。。。どうかお知恵をお貸しください。よろしくお願いいたします。

KAZUMiXKAZUMiX 2011/05/20 11:16 縦のセンタリングは難しいです。
「CSS 縦 センタリング」で検索すると様々な手法が見つかりますので、そこから目的に合うものをアレンジして使用するのが良いと思います。

kabkab 2011/05/20 15:04 ご回答ありがとうございます。
やっぱり難しいですか。
section1のセンタリングはできてるのですが、
section7のセンタリングがどうしてもうまくいかなくて。。
もう少し調べてみます。
何かほんの些細なヒントでもありましたら、またお教え下さい。
ありがとうございました。

ちん。ちん。 2011/07/12 00:38 動作が気持ちよく以前から使わせていただいてますが、1点だけ気になる部分があります。
アンカー部分にスクロールした際、URLの最後に「#アンカー名」が付いてしまいますが、これを付加されないようにはできないものでしょうか。

KAZUMiXKAZUMiX 2011/07/12 10:36 以下の部分を削除すればOKです。
location.hash = targetHash;

ちん。ちん。 2011/07/12 12:03 できました!
素早い回答ありがとうございます。

いせいせ 2011/07/18 00:48 はじめまして。
先日このスクリプトを見つけ自サイトに適応してみようと思ったのですが、サイズ指定(500x500)した<div>内にサンプルページっぽいもの(500x500の9マス)を組み込んだのですが機能しませんでした。
<div>のサイズ指定を無くすと機能しますがこれは仕様がないのでしょうか。
テレビ窓っぽくしたいのですが、自己解決出来ませんでした。ご教授お願いします。

じょむじょむ 2011/11/07 20:25 はじめまして、色々と探していたらこちらの素晴らしいscriptにたどり着きました。
とても気持ち良く動いてくれますね!
横にもキレイに動いてくれて、さっそく使わせていただきます。(*^_^*)


一つ質問なのですが、

#アンカー名を付加させないようにできるというやり取りを拝見し、
この箇所をコメントアウトしました。
location.hash = targetHash;

同一ページ内では確かにURLにid名が表示されないのですが、
他のページからのリンクではid名が付加されてしまいました。

これを回避する方法はありますか…?

jj 2012/02/02 02:51 safari5での挙動についてですが、ヘッダー固定などでposition:absoluteを使うと動かなくなるようです。
ほかの主要ブラウザ(最新版)では問題なく稼働しました。

まもまも 2012/02/28 13:07 非常に質の高いスクリプトですね!!

ひとつだけ…
画面の一番上に行くよく使う動きなんですが、
動きの最後に「カクッ」と動いてしまうのを
なんとかできないでしょうか??

てつてつ 2013/05/13 20:53 初めまして、これから使わせて頂こうと思ってます。
smoothScroll.jsという下記のプラグイン
http://blog.webcreativepark.net/2007/07/12-143406.html

こちらにある機能の、他のScriptでアンカータグを使っている場合に特定のリンクではこのscrollsmoothlyをアクションさせない回避方法は用意されてませんか?

もしなければ、どこに回避させる条件文を書くといいかのヒントだけでももらえれば・・・と思います!
宜しく御願いします。

kazukazu 2013/09/18 20:58 素晴らしいです。自力でHPを立ち上げようと試みております。
スクロールもそうですが、常にブラウザーにあった表示をするにはどのようにすればよいのでしょうか?
お気に入りが左側にあるときとないときでも正常に表示されておりますが、スタイルシートの作成が不可欠になりますでしょうか?

momomomo 2014/03/06 16:52 いつも愛用させていただきありがとうございます。

★前述の"てつ"さんと同じ要望になります〜
今回Fancybox(jQueryプラグイン)と一緒に使用したところ、意図しない動きをしてしまい悩んでいます。

http://ameblo.jp/shun-jp/entry-11174778648.html

↑上記サイトに特定の要素にのみ適用させる方法というのはあったのですが、そうではなく、特定のリンクにのみ適用させたくない場合の方法がわかりません。

javascriptはこれから勉強しないと・・・と思っておりますが、まだ素人なのでできるだけ詳しく教えていただけると助かります。何卒ご教授くださいませ。

もつもつ 2014/03/13 17:30 とても助かっています!いつもありがとうございます!

私もmomoさんとまったく同じ現象で悩んでおります。
すでにscrollsmoothly.jsを使用しているページにfancyboxを入れたところ、バッティングしてページトップにスムースリンクしてしまいます。動かしたい要素のclassにe.preventDefault();を記述してもダメでした。

使いやすいのでできればこのままscrollsmoothly.jsを使わせていただきたいのですが、やはり共存させるのは難しいのでしょうか・・・。

知識が浅くて大変申し訳ないのですが、無理なのかどうかだけでも教えていただけるととてもありがたいです。

もつもつ 2014/03/13 17:30 とても助かっています!いつもありがとうございます!

私もmomoさんとまったく同じ現象で悩んでおります。
すでにscrollsmoothly.jsを使用しているページにfancyboxを入れたところ、バッティングしてページトップにスムースリンクしてしまいます。動かしたい要素のclassにe.preventDefault();を記述してもダメでした。

使いやすいのでできればこのままscrollsmoothly.jsを使わせていただきたいのですが、やはり共存させるのは難しいのでしょうか・・・。

知識が浅くて大変申し訳ないのですが、無理なのかどうかだけでも教えていただけるととてもありがたいです。

もつもつ 2014/03/13 17:30 とても助かっています!いつもありがとうございます!

私もmomoさんとまったく同じ現象で悩んでおります。
すでにscrollsmoothly.jsを使用しているページにfancyboxを入れたところ、バッティングしてページトップにスムースリンクしてしまいます。動かしたい要素のclassにe.preventDefault();を記述してもダメでした。

使いやすいのでできればこのままscrollsmoothly.jsを使わせていただきたいのですが、やはり共存させるのは難しいのでしょうか・・・。

知識が浅くて大変申し訳ないのですが、無理なのかどうかだけでも教えていただけるととてもありがたいです。

もつもつ 2014/03/13 17:30 とても助かっています!いつもありがとうございます!

私もmomoさんとまったく同じ現象で悩んでおります。
すでにscrollsmoothly.jsを使用しているページにfancyboxを入れたところ、バッティングしてページトップにスムースリンクしてしまいます。動かしたい要素のclassにe.preventDefault();を記述してもダメでした。

使いやすいのでできればこのままscrollsmoothly.jsを使わせていただきたいのですが、やはり共存させるのは難しいのでしょうか・・・。

知識が浅くて大変申し訳ないのですが、無理なのかどうかだけでも教えていただけるととてもありがたいです。

もつもつ 2014/03/13 17:30 とても助かっています!いつもありがとうございます!

私もmomoさんとまったく同じ現象で悩んでおります。
すでにscrollsmoothly.jsを使用しているページにfancyboxを入れたところ、バッティングしてページトップにスムースリンクしてしまいます。動かしたい要素のclassにe.preventDefault();を記述してもダメでした。

使いやすいのでできればこのままscrollsmoothly.jsを使わせていただきたいのですが、やはり共存させるのは難しいのでしょうか・・・。

知識が浅くて大変申し訳ないのですが、無理なのかどうかだけでも教えていただけるととてもありがたいです。

もつもつ 2014/03/13 17:30 とても助かっています!いつもありがとうございます!

私もmomoさんとまったく同じ現象で悩んでおります。
すでにscrollsmoothly.jsを使用しているページにfancyboxを入れたところ、バッティングしてページトップにスムースリンクしてしまいます。動かしたい要素のclassにe.preventDefault();を記述してもダメでした。

使いやすいのでできればこのままscrollsmoothly.jsを使わせていただきたいのですが、やはり共存させるのは難しいのでしょうか・・・。

知識が浅くて大変申し訳ないのですが、無理なのかどうかだけでも教えていただけるととてもありがたいです。

CJ?ごろうCJ?ごろう 2014/03/15 23:31 こちらのスクリプトを私好みの動作になるよう、次のように改造させていただきました。

●イージング処理:スクロールを「開始 → 加速 → 減速 → 停止」に変更。

●スクロールの中断処理を追加。

また、改造した物をライセンスを継承して公開した事を報告します。

はかたはかた 2015/07/14 13:14 素敵なスクリプトありがとうございます。是非利用させていただきたいと思っています。

設置先のサイトがページ上部に固定グローバルナビをおいています。
その高さ分(100px)だけ、スクロールを引きたいのですが、

targetYからその分差し引けばいいかと思うのですが、なかなかうまくできません。
お手数ではございますが、ご教授いただけますでしょうか

はかたはかた 2015/07/14 13:14 素敵なスクリプトありがとうございます。是非利用させていただきたいと思っています。

設置先のサイトがページ上部に固定グローバルナビをおいています。
その高さ分(100px)だけ、スクロールを引きたいのですが、

targetYからその分差し引けばいいかと思うのですが、なかなかうまくできません。
お手数ではございますが、ご教授いただけますでしょうか

大西大西 2015/11/10 15:05 はじめまして。
現在、これを使ってサイトを制作中なのですが
例えば、セクション2から閲覧を開始したい場合はどうしたらよいのでしょうか?J-Queryはさっぱりなのでご教授いただけたら幸いでございます。

ひろひろ 2015/11/10 22:36 はじめまして、わたしもこちらの素晴らしいスクリプトを使用させていただいております。
固定ヘッダーの場合、クロームは上手く動くのですが、firefoxとieがスクロールごにガクッとヘッダー分移動してしまいます。
どこにヘッダーの高さを追加すれば上手く動きますでしょうか?