質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

493閲覧

Vue.js スムーススクロール

kurio

総合スコア24

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2019/02/10 02:58

前提・実現したいこと

Vue.jsでページ内リンクのスムーススクロールを実現したいです。aタグの「次へ」をクリックした時に、
jsスムーススクロール2ページ目の場所へスムーススクロールをさせたいのですが
スムーススクロールができておりません。jsfiddleで試しているのですが、特にエラーは
表示されておらず、このような場合どのように修正していけば良いのか教えていただけないでしょうか。
お願いいたします。

該当のソースコード

○ HTML

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Vue.js App</title> <style> body { margin: 0; padding: 0; text-align: center; } .slide { width: 100%; height: 100vh; display: flex; align-items: center; justify-content: center; flex-direction: column; } </style> </head> <body> <div class="slide" id="s1"> <h1>jsスムーススクロール1ページ目</h1> <a href="#s2" @click="clickHadle">次へ</a> </div> <div class="slide" id="s2"> <h1>jsスムーススクロール2ページ目</h1> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script> </body> </html>

○javascript

new Vue({ el:'#s1', methods:{ clickHadle:function(){ let smoothScrollRequestId = null; const smoothScrollTo = function(x, y){ const duration = 500; // スムーススクロールが完了するまでの時間 [ms] (必要に応じて変更) const easing = function (t, b, c, d) { // 移動量の計算関数 (同上) return -c *(t/=d)*(t-2) + b; }; const startX = window.pageXOffset, startY = window.pageYOffset; // 初期スクロール位置 const cx = x - startX, cy = y - startY; // 終了値 const startTime = new Date().getTime(); // 開始時刻 let t = 0; // 現在時刻 const scroll = function(){ t = new Date().getTime() - startTime; window.scrollTo(startX + easing(t, 0, cx, duration), startY + easing(t, 0, cy, duration)); if (t < duration) smoothScrollRequestId = requestAnimationFrame(scroll); }; cancelAnimationFrame(smoothScrollRequestId); smoothScrollRequestId = requestAnimationFrame(scroll); }; // クリック時 if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.msMatchesSelector; // https://developer.mozilla.org/ja/docs/Web/API/Element/matches document.addEventListener("click", function(e){ const href = e.target.getAttribute("href"); if (!e.target.matches("a[href^='#'], a[href^='#'] *")) return; // 内部リンク以外は何もしない const dest = href == top ? document.body : document.getElementById(href.slice(1)); // 移動先 if (!dest) return; const y = (function(e){ return e.getBoundingClientRect().top + window.pageYOffset })(dest); // 移動先の、最上位要素からのY座標 smoothScrollTo(0, y); e.preventDefault(); }); } } });

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

JSfiddleで実行したところ、私の環境(mac OS, chrome)では「次へ」をクリックしたタイミングでコンソールにエラーがでます。

Uncaught DOMException: Blocked a frame with origin "https://fiddle.jshell.net" from accessing a cross-origin frame. at HTMLDocument.<anonymous> (https://fiddle.jshell.net/7h2stymw/1/show/:64:27)

しっかりと調べていませんが、JSのソースコードがブラウザのセキュリティ設定にひっかかっているのではないでしょうか。

また蛇足ですが、 Vueであれば自分でJSコードを書かずともスムーススクロールできるパッケージがあります。
https://github.com/rigor789/vue-scrollto#readme
(ご存知の上でしたらすみません!)

<追記>
JSのmethodのclickeHadle内を見ると、そのメソッド自体がクリックイベントに反応して発火するはずなのに中身にイベントリスナが書かれているのが怪しかったので、それを消して、yに適当な数値を入れて動かすとスムーススクロールうまくいきました。
その周辺のコードを修正してみてはいかがでしょうか。

<追記2>
こちらが動作したコードです。

js

1new Vue({ 2el:'#s1', 3methods:{ 4clickHadle:function(){ 5 let smoothScrollRequestId = null; 6 const smoothScrollTo = function(x, y){ 7 const duration = 500; // スムーススクロールが完了するまでの時間 [ms] (必要に応じて変更) 8 const easing = function (t, b, c, d) { // 移動量の計算関数 (同上) 9 return -c *(t/=d)*(t-2) + b; 10 }; 11 12 const startX = window.pageXOffset, startY = window.pageYOffset; // 初期スクロール位置 13 const cx = x - startX, cy = y - startY; // 終了値 14 const startTime = new Date().getTime(); // 開始時刻 15 let t = 0; // 現在時刻 16 const scroll = function(){ 17 t = new Date().getTime() - startTime; 18 window.scrollTo(startX + easing(t, 0, cx, duration), startY + easing(t, 0, cy, duration)); 19 if (t < duration) smoothScrollRequestId = requestAnimationFrame(scroll); 20 }; 21 cancelAnimationFrame(smoothScrollRequestId); 22 smoothScrollRequestId = requestAnimationFrame(scroll); 23 }; 24 // クリック時 25/* if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.msMatchesSelector; */ 26/* const href = e.target.getAttribute("href"); 27 if (!e.target.matches("a[href^='#'], a[href^='#'] *")) return; // 内部リンク以外は何もしない 28 29 const dest = href == top ? document.body : document.getElementById(href.slice(1)); // 移動先 30 if (!dest) return; */ 31 32 const y = 300 // yに適当な値を代入 33 smoothScrollTo(0, y); 34 35/* e.preventDefault(); */ 36 37} 38} 39});

投稿2019/02/12 07:35

編集2019/02/13 04:07
yu-smc

総合スコア610

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kurio

2019/02/12 11:44

yu-smcさま ご回答頂き誠にありがとうございます。 ライブラリにつきましてもありがとうございます。試して見たいと思います。 >JSのmethodのclickeHadle内を見ると、そのメソッド自体がクリックイベントに反応して発火するはずな>のに中身にイベントリスナが書かれているのが怪しかったので、それを消して、yに適当な数値を入れて動>かすとスムーススクロールうまくいきました。 >その周辺のコードを修正してみてはいかがでしょうか。 確かにおっしゃる通りですね。中身にイベントリスナを記載しておりました。 こちらにつきまして、消しいただいた箇所とは 「document.addEventListener("click", 」の部分でしょうか。 こちらでやって見たのですが、うまくできなかったのですが 修正いただいたJSfiddleを共有いただくことは可能でしょうか。 よろしくお願い申し上げます。
yu-smc

2019/02/13 04:08

返答おそくなりすみません!回答に追記しました。 ごっそり消しているのは、document.addEventListener("click"を消したため 'e' が使えないからです。
kurio

2019/02/13 12:33

yu-smcさま コードを共有頂きありがとうございます! 無事動かすことができました。 >>document.addEventListener("click"を消したため 'e' が使えないからです。 こちら理解いたしました。 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問