javascript/他ページ内リンクでもスムーズスクロールさせたい

このQ&Aのポイント
  • ページ間の内部リンクでもスムーズなスクロールを実現したい場合、JavaScriptを使用することで簡単に実装することができます。
  • 特定の要素へのリンクをクリックした際にアニメーション的なスクロール効果を適用させるためのコードを記述することで、スムーズなページ内リンクを実現することができます。
  • ページ間のリンクにも同様のスクロール効果を適用したい場合、リンク先のURLを取得し、ページ内の該当要素までスクロールする処理を追加することで実現することができます。
回答を見る
  • ベストアンサー

javascript/他ページ内リンクでもスムーズスクロールさせたい

javascript/他ページ内リンクでもスムーズスクロールさせたい お世話になります。 page1.htmlのページ内リンクにスムーズスクロールを設定しています。ページ内に#aとアンカー設定し、page1.html内で移動するときはもちろん問題ありません。 これをpage2.htmlからpage1.html#aにリンクさせる際にもスムーズスクロールで移動させるにはどうしたら良いのでしょうか? そもそもそんなことはできないのでしょうか? ソースを書かせていただきたいのですが、文字数が足りません。とりあえず最初の方だけ書きます。 var ss = { fixAllLinks: function() { var allLinks = document.getElementsByTagName('a'); for (var i=0;i<allLinks.length;i++) { var lnk = allLinks[i]; if ((lnk.href && lnk.href.indexOf('#') != -1) && ( (lnk.pathname == location.pathname) || ('/'+lnk.pathname == location.pathname) ) && (lnk.search == location.search)) { ss.addEvent(lnk,'click',ss.smoothScroll); } } }, smoothScroll: function(e) { if (window.event) { target = window.event.srcElement; } else if (e) { target = e.target; } else return; if (target.nodeName.toLowerCase() != 'a') { target = target.parentNode; } if (target.nodeName.toLowerCase() != 'a') return; anchor = target.hash.substr(1); var allLinks = document.getElementsByTagName('a'); var destinationLink = null; for (var i=0;i<allLinks.length;i++) { var lnk = allLinks[i]; if (lnk.name && (lnk.name == anchor)) { destinationLink = lnk; break; } } 続きは補足欄に書かせていただけそうなら書きます。 中途半端な情報かつ長文で申し訳ありません。 どんな些細なことでも構いませんので、アドバイスいただけないでしょうか。 どうぞよろしくお願いいたします。

noname#127702
noname#127702

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

以下は、実際に組んだことはありませんが私なりの大まかな考えです。 ■まずはじめに  page2.html 内にスクロール対象となる <a name="a" id="a">●●●</a> はHTMLで書かない。 ■なぜか  page2.html が読み込まれた時点でブラウザが通常通りの振る舞いで #a の位置へパッとスクロールしてしまいます。 ■どうするか  page2.html のスクロール対象となる位置は HTML で <a id="a_">●●●</a> とする。  id は仮の id です。目印に「_」をつけています。 ■つぎに  document がロードされた時点で id と name を書き換えます。  書き換え前 → <a id="a_">●●●</a>  書き換え後 → <a name="a" id="a">●●●</a> ■あと一息  id="a" の 位置を取得。  setTimeout と scrollTo 関数を、ちまちまと目的の id="a" にたどり着くまで実行する。 ■おしまいに  ・私が好んで使う JavaScript のフレームワークを紹介します。   http://www.prototypejs.org/  ・prototype.js を使うと    // 縦の位置を取得    http://www.prototypejs.org/api/element/cumulativeoffset    $('a'),cumulativeOffset().top // ← id="a" の縦位置が取得出来ます。        // イベント観察をし、関数を実行する。    http://www.prototypejs.org/api/event/observe    Event.observe(document, 'load', function(){     // 試しにロード後にタイトルを書き換えてみます     document.title += new Date();    });    // エレメントの書き換え    http://www.prototypejs.org/api/element/update  などなど、ここでは紹介しきれないぐらい楽しい機能がついています。  Firefox、Internet Explorer 等のブラウザの違いを意識しにくい JavaScript を書くことが身につきます。  残念ながら、スムーススクロールはついていません。

noname#127702
質問者

お礼

ご回答ありがとうございます。お礼が大変遅くなり、申し訳ありません。 現状のjavascriptに何か加えるのかと思っていたのですが、そういう手順で分解して考えればいいのですね! javascriptの知識はほとんどなく、いつもネット上で紹介されているものをコピペばかりだったのですが、いよいよじっくり取り組むときが来たようです。 がんばってみます! 分かりやすく、丁寧にお教え下さりありがとうございました。 やってみてまた分からなくなったら質問投稿させていただきます。 もしご縁がありましたら、またよろしくお願いいたします。 お忙しいところありがとうございました!

その他の回答 (1)

回答No.2

> これをpage2.htmlからpage1.html#aにリンクさせる際にもスムーズスクロールで移動させるにはどうしたら良いのでしょうか? window.onloadのタイミングでwindow.location.hashに何か入ってたらスクロールを開始してみてください。 ちなみに<div id="hoge">という書き方でも<a href="#hoge">が有効です。

noname#127702
質問者

お礼

ご回答ありがとうございます。お礼が大変遅くなり、申し訳ありません。 >window.onloadのタイミングでwindow.location.hashに何か入ってたらスクロールを開始してみてください。 とは、現在のjavascriptファイルにそういう命令文を加えるということでよいのでしょうか?? 私にjavascriptの知識がなくついていけてません…。 もう少し勉強して出直します> <;; ありがとうございました。 せっかく教えて下さったのにすぐ理解できず申し訳ありませんでした!

関連するQ&A

  • Javascriptの修正がわかりません

    ルート「/」からの設定をkaitoフォルダー「/kaito/」に変更したいのですが、どこを修正すればいいのかわかりません。 $(function () { var url = location.pathname ; var ary = url.split("/"); while ( ary.length >= 3 ) { ary.pop(); } var str = ary.join("/")+"/"; if ( str == "//" ) str = "/"; var target = $("#gnav ul").children("li").children('a[href="'+str+'"]'); if ( target.length <= 0 ) return ; var imgPath = target.children("img").attr("src"); target.children("img").attr("src",imgPath.replace( /_o(\.[a-z]+)$/, "_a"+"$1")); });

  • スムーズスクロールとfleXcrollの併用

    よろしくお願い致します。 jQueryを使用して、「overflow: auto」を指定している要素内でスムーズスクロール出来る方法を探しており、以下のようなコードを見つけました。 $(document).ready(function(){ var box = $('#contents'); $(document).click(function(event){ var obj = $(event.target); var anchor = obj.filter('a[href*="#"]'); if (!anchor[0]) anchor = obj.parents('a[href*="#"]'); if (anchor[0]){ var target = $(anchor[0].hash, box); if (target[0]){ var scrollTop = box.scrollTop(); var dist1 = box.prop('scrollHeight') - box.prop('clientHeight') - scrollTop; var dist2 = target.position().top - box.position().top; box.animate({ scrollTop: scrollTop + Math.min(dist1, dist2)}); return false; } } return true; }); }); ↑このコードで「overflow:auto;」を指定している要素内でスムーズスクロールが出来るようになったのですが、スクロールバーを装飾できる「fleXcroll(http://shanabrian.com/web/library/flexcroll.php)」プラグインと併用すると、スムーズスクロールが効かなくなってしまいます。 「fleXcroll」のコードは「http://www.hesido.com/web/flexcroll.js」になる(記述が長くここには書ききれませんでした)のですが、薄識のため何処に問題があるのか分からない状態です。 ちなみにHTMLは、下記のようなコードで使用しています。 <div id="navi">  <ul>   <li><a href="#A">divAへ移動</a></li>   <li><a href="#B">divBへ移動</a></li>   <li><a href="#C">divCへ移動</a></li>   <li><a href="#D">divDへ移動</a></li>   <li><a href="#E">divEへ移動</a></li>  </ul> </div> <div id="hoge" style="height:500px; overflow:auto;">  <div id="A">divAの内容</div>  <div id="B">divBの内容</div>  <div id="C">divCの内容</div>  <div id="D">divDの内容</div>  <div id="E">divEの内容</div> </div> 分かりにくい説明で恐れ入ります。 補足説明致しますので、お分かりになる方がいらっしゃいましたら、どうかご教授下さいますようお願い致します。

  • rel属性を複数使用したい

    XHTML 1.0 Strictなのでtarget="_blank"の代用で外部jsに function externalLinks() { if (!document.getElementsByTagName) return; var anchors = document.getElementsByTagName("a"); for (var i=0; i<anchors.length; i++) { var anchor = anchors[i]; if (anchor.getAttribute("href") && anchor.getAttribute("rel") == "external") anchor.target = "_blank"; } } window.onload=externalLinks; として読み込みリンクに<a rel="external" ..........>としています。 その他にhighslide.jsを使用しているのですがrel属性が重複しているためか highslide.jsの動作は正常なのですがtarget="_blank"の代用の効果がありません。 rel属性が重ならないようにしたいのですが解決策はありますでしょうか? highslide.jsのURLです↓ http://vikjavev.no/highslide/

  • パララックスページスクロールについて

    こんにちは。 下記のコードはJQUERYコードをコピペしたもので、ド素人です。 ナビをクリックすると、各コンテンツBOXにいきますが、下のコードだとTOPの一番上まで来てしまいます、 クリック→ページトップから下へ85pxのところに来るように設定したいのですが。 ========javascript==================== <script> //スムーススクロール 各コンテンツbox// $(function() { $(".scroll").click(function(event){ event.preventDefault(); var url = this.href; var parts = url.split("#"); var target = parts[1]; var target_offset = $("#"+target).offset(); var target_top = target_offset.top; $('html, body').animate({scrollTop:target_top}, 1200); }); }); </script> =================HTML==================== <nav> <ul id="dropmenu"> <li><a href="#top" class="scroll">Top</a></li> <li><a href="#introduce" class="scroll">薬膳レシピとは</a></li> <li><a href="#basictypecheck" class="scroll">基本体質のチェック</a></li> <li><a href="#typedescription" class="scroll">気・血・水について</a></li> <li><a href="#mix" class="scroll">混合タイプの特徴</a></li> <li><a href="#notfeelingcheck" class="scroll">不調の原因チェック</a> <li><a href="#Profile" class="scroll">Profile</a></li> <li><a href="#Lesson" class="scroll">Lesson</a></li> </ul> </nav> ===================================== 他にもコードが必要であれば、ご教示いただければ補足します。 どうぞ宜しくお願い致します。

  • javascriptで困っています

    マウスがブラウザーの外側から出ると、ポップアップが出るようにしたいです。 loadEvents: function() { this.addEvent(document, "mouseout", function(e) { e = e ? e : window.event; if(e.target.tagName.toLowerCase() == "input") return; var vpWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); if(e.clientX >= (vpWidth - 50)) return; if(e.clientY >= 50) return; var from = e.relatedTarget || e.toElement; if(!from) bioEp.showPopup(); }.bind(this)); 現在は、上方向に出るとポップアップが出ます。 左右にマウスが出た時に、ポップアップ出るにはどう記述すれば良いでしょうか。 よろしくお願いいたします。

  • javascriptによるスクロールを縦から横に変換したい

    拾ったソースを改造しようとしているのですが 知識がない為うまくいきません。 divの中のsample1~10を横に並べて、改行なしの横スクロールにしたいです。 今は縦スクロールです。 どこを直せばいいのか教えてくださいm(_ _)m ―――――――――――――――――― <SCRIPT language="JavaScript"> <!-- var SmoothScroll = {}; SmoothScroll = { targetScrollTop : 0, dist : 0, timer : 0, count : 0, parentid : 0, lastDist : 0, //speedStore : [], options : {}, defaultOptions : { time : 1*1000, unit : 50 }, scrollTo : function( element, parent, options ){ this.options.time = this.defaultOptions.time; this.options.unit = this.defaultOptions.unit; if( options ){ this.options.time = ( options.time ) ? options.time : this.options.time; this.options.unit = ( options.unit ) ? options.unit : this.options.unit; } clearInterval( this.timer ); this.parentid = parent; this.scrollTopMax = this.$(parent).scrollHeight - this.$(parent).offsetHeight + parseInt(this.$(parent).style.borderTopWidth) + parseInt(this.$(parent).style.borderBottomWidth); if( navigator.userAgent.match( "MSIE" ) ){ this.targetScrollTop = ( element ) ? this.$(element).offsetTop : 0; }else{ var targetOffsetTop = ( element ) ? this.$(element).offsetTop : this.$(parent).offsetTop; this.targetScrollTop = targetOffsetTop - this.$(parent).offsetTop; } this.targetScrollTop = ( this.targetScrollTop > this.scrollTopMax ) ? this.scrollTopMax : this.targetScrollTop; this.dist = this.targetScrollTop - this.$(parent).scrollTop; this.lastDist = 0; this.timer = setInterval('SmoothScroll.update()', this.options.unit ); this.count = 0; //this.speedStore = []; this.update(); }, update : function(){ var dist = this.targetScrollTop - this.$(this.parentid).scrollTop; var speed = 2 * dist * this.options.unit / ( this.options.time - this.options.unit * this.count ); //this.speedStore.push( speed ); speed = ( speed > 0 ) ? Math.ceil( speed ) : Math.floor( speed ); if( Math.abs(dist) <= Math.abs(speed) ){ // got there clearInterval( this.timer ); this.$(this.parentid).scrollTop = this.targetScrollTop; return; }else if( this.lastDist == dist ){ // stuck clearInterval( this.timer ); this.$(this.parentid).scrollTop = this.targetScrollTop; return; } var scrollTop = this.$(this.parentid).scrollTop + speed; this.$(this.parentid).scrollTop = scrollTop; this.lastDist = dist; this.count++; if( this.count == this.options.time / this.options.unit ){ // timeout clearInterval( this.timer ); this.$(this.parentid).scrollTop = this.targetScrollTop; } }, $ : function(id) { return document.getElementById(id); } } --> </script> <div id="scrolltop" style="width: 750px; height: 200px; overflow-x: scroll; overflow-y: scroll; border: 1px black solid;"> <a href="sample1">1</a> <a href="sample2">2</a> <a href="sample3">3</a> <a href="sample4">4</a> <span id="middle" style="color: red"> <a href="sample5">5</a> </span> <a href="sample6">6</a> <a href="sample7">7</a> <a href="sample8">8</a> <a href="sample9">9</a> <span id="bottom" style="color: blue"> <a href="sample10">10</a> </span><br /> </div> <input type="button" value="go to top" onclick="SmoothScroll.scrollTo(0,'scrolltop');"/> <input type="button" value="go to middle" onclick="SmoothScroll.scrollTo('middle','scrolltop');"/> <input type="button" value="go to bottom" onclick="SmoothScroll.scrollTo('bottom','scrolltop');"/>

  • テキストノードを非表示にできません

    いつもお世話になります。 <div id="ida"> <div>aaaaaaaaaaaa</div> </div> のとき、 elemDiv=document.getElementById("ida"); var nodes=elemDiv.childNodes; for(i=0;i<nodes.length;i++) {   var node=nodes[i];   if(node.nodeName.toLowerCase()=='div'){     node.style.display='none'   } } とすれば、<div>aaaaaaaaaaaa</div> は、表示されなくなります。 ここで、 <div id="ida"> aaaaaaaaaaaa </div> として、つまり文字列を<div>で囲まないようにして for(i=0;i<nodes.length;i++) {   var node=nodes[i];   if(node.nodeName=='#text'){     node.style.display='none'   } } とすると、「aaaaaaaaaa」が非表示となりません。 テキストノード自体を非表示にすることはできないのでしょうか。 よろしくお願いいたします。

  • アメーバブログに外部Javascriptを利用して、以下を実現したいの

    アメーバブログに外部Javascriptを利用して、以下を実現したいのですが可能でしょうか? 【実現したい】 ・各記事に表示 ・リツイートボタン ・各ソーシャルブックマーク ・「Facebookのいいね」ボタン 【可能な限り一つのjavascriptで実現したい】 リツイートボタンを実現しているjavascriptに、「各ソーシャルブックマーク」と「facebookのいいねボタン」を組み込みたいです。 ▼リツイートボタンのjavascript▼ <!-- $(document).ready(function(){ var tid = 'twitteracount'; var page_url = location.href; if (page_url.match(/^.+\/entrylist[\-0-9]*\.html$/g )) { var entries = $(".newentrytitle a"); var classname = ".updatetime"; var flg = 0; } else { var entries = $(".foot a:contains('記事URL')"); var classname = "div.entry .subContents"; var flg = 1; } for (i = 0; i < entries.length; i++) { var url = entries[i]; if (flg == 0) { title = entries.eq(i).text(); } else { title = $("div.entry h3.title").eq(i).text(); } var twitter_btn = '<p>この記事を共有する</p><a href="http://twitter.com/home/?status=' + encodeURIComponent('RT @'+tid+': '+title + ' ' + url) + '" target="_blank"><img border="0" alt="ツイッターに投稿する" src="../common/twitter/button/twitter-button038.png" /></a>'; $(classname).eq(i).append(' <div style="background: none repeat scroll 0% 0% rgb(255, 255, 255); border: 1px dotted rgb(153, 153, 153); padding: 8px;">' + twitter_btn + '</div> '); } }) // --> ▼ソーシャルブックマーク▼ <a href='javascript:location.href="http://b.hatena.ne.jp/add?mode=confirm&amp;url="%2bencodeURIComponent(location.href)%2b"&amp;title="%2bencodeURIComponent(document.title);' style="font-size:12px; text-decoration:none;"><img src="common/img/hatenasbm.gif" alt="はてなブックマーク" width="14" height="12" /></a>

  • javascriptについて

    現在HPを作成していてjavaのプルダウンメニューを設置していますが 最初からメニューが開いた状態になります。ちなみにsdmenu.jsを使用しています。 最初開いた時にメニューが閉じるようにできますでしょうか? function SDMenu(id) { if (!document.getElementById || !document.getElementsByTagName) return false; this.menu = document.getElementById(id); this.submenus = this.menu.getElementsByTagName("div"); this.remember = true; this.speed = 4; this.markCurrent = true; this.oneSmOnly = false; } SDMenu.prototype.init = function() { var mainInstance = this; for (var i = 0; i < this.submenus.length; i++) this.submenus[i].getElementsByTagName("span")[0].onclick = function() { mainInstance.toggleMenu(this.parentNode); }; if (this.markCurrent) { var links = this.menu.getElementsByTagName("a"); for (var i = 0; i < links.length; i++) if (links[i].href == document.location.href) { links[i].className = "current"; break; } } if (this.remember) { var regex = new RegExp("sdmenu_" + encodeURIComponent(this.menu.id) + "=([01]+)"); var match = regex.exec(document.cookie); if (match) { var states = match[1].split(""); for (var i = 0; i < states.length; i++) this.submenus[i].className = (states[i] == 0 ? "collapsed" : ""); } } }; SDMenu.prototype.toggleMenu = function(submenu) { if (submenu.className == "collapsed") this.expandMenu(submenu); else this.collapseMenu(submenu); }; SDMenu.prototype.expandMenu = function(submenu) { var fullHeight = submenu.getElementsByTagName("span")[0].offsetHeight; var links = submenu.getElementsByTagName("a"); for (var i = 0; i < links.length; i++) fullHeight += links[i].offsetHeight; var moveBy = Math.round(this.speed * links.length); var mainInstance = this; var intId = setInterval(function() { var curHeight = submenu.offsetHeight; var newHeight = curHeight + moveBy; if (newHeight < fullHeight) submenu.style.height = newHeight + "px"; else { clearInterval(intId); submenu.style.height = ""; submenu.className = ""; mainInstance.memorize(); } }, 30); this.collapseOthers(submenu); }; SDMenu.prototype.collapseMenu = function(submenu) { var minHeight = submenu.getElementsByTagName("span")[0].offsetHeight; var moveBy = Math.round(this.speed * submenu.getElementsByTagName("a").length); var mainInstance = this; var intId = setInterval(function() { var curHeight = submenu.offsetHeight; var newHeight = curHeight - moveBy; if (newHeight > minHeight) submenu.style.height = newHeight + "px"; else { clearInterval(intId); submenu.style.height = ""; submenu.className = "collapsed"; mainInstance.memorize(); } }, 30); }; SDMenu.prototype.collapseOthers = function(submenu) { if (this.oneSmOnly) { for (var i = 0; i < this.submenus.length; i++) if (this.submenus[i] != submenu && this.submenus[i].className != "collapsed") this.collapseMenu(this.submenus[i]); } }; SDMenu.prototype.expandAll = function() { var oldOneSmOnly = this.oneSmOnly; this.oneSmOnly = false; for (var i = 0; i < this.submenus.length; i++) if (this.submenus[i].className == "collapsed") this.expandMenu(this.submenus[i]); this.oneSmOnly = oldOneSmOnly; }; SDMenu.prototype.collapseAll = function() { for (var i = 0; i < this.submenus.length; i++) if (this.submenus[i].className != "collapsed") this.collapseMenu(this.submenus[i]); }; SDMenu.prototype.memorize = function() { if (this.remember) { var states = new Array(); for (var i = 0; i < this.submenus.length; i++) states.push(this.submenus[i].className == "collapsed" ? 0 : 1); var d = new Date(); d.setTime(d.getTime() + (30 * 24 * 60 * 60 * 1000)); } };

  • javascriptでスマートフォン・PC分岐

    PC用のサイトとスマートフォン用のサイトをそれぞれ作り、アクセスをjavascriptで振り分けたいと考えています。 PC用とスマートフォン用のURLはあいだに"i"をはさむ違いだけです。 http://www.hoge/cate1/post_001.html http://www.hoge/i/cate1/post_001.html いろいろ調べた結果、トップページは下記でうまく行きました。 <script type="text/javascript"> if ((navigator.userAgent.indexOf('iPhone') > 0 && navigator.userAgent.indexOf('iPad') == -1) || navigator.userAgent.indexOf('iPod') > 0 || navigator.userAgent.indexOf('Android') > 0) { location.href = '/i/'; } </script> 問題は個別ページがうまく行きません。自分なりに調べて下記のように書きました。 <script type="text/javascript"> if ((navigator.userAgent.indexOf('iPhone') > 0 && navigator.userAgent.indexOf('iPad') == -1) || navigator.userAgent.indexOf('iPod') > 0 || navigator.userAgent.indexOf('Android') > 0) { location.href = '/i/location.pathname'; } </script> ところがこれではhttp://www.hoge/i/location.pathnameに行ってしまいダメです。 なぜダメなのでしょうか? この場合、どのように記述すれば良いか教えてください。 PHPとCGIとかはさっぱり判らないのでその選択肢はありません。 よろしくお願いします。

専門家に質問してみよう