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

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

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

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

Q&A

解決済

3回答

1784閲覧

TOPへ戻るボタンの表示・非表示について

退会済みユーザー

退会済みユーザー

総合スコア0

CSS3

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

0グッド

0クリップ

投稿2018/08/03 01:43

編集2018/08/03 02:30

前提・実現したいこと

現在TOPへ戻るボタンの実装をしようとしております。

動きとして実装したい事は、

・スクロールを100pxしたらボタンが表示

・スクロールを一番下まで行った時にはボタンを非表示にして、上にスクロールをした時には再度ボタンを表示させたい

このような動きのボタンの実装をしたいです。

初心者で調べてみても上記それぞれ片方ずつの処理については書いてあるのですが、同時に処理をする時の書き方がわからず困っております。 どうかご教授をいただければと思っております。 

よろしくお願いいたします。

発生している問題・エラーメッセージ

下記のプログラムを書いて起こっている事は、

・スクロールを100pxした時にボタンが表示される際に点滅した後に表示される。

・一番下までスクロールした際にはPCブラウザでは非表示になるが、iPhoneのsafariで確認した際に非表示にならない。 一番下から上にスクロールした時に表示されるのは問題なく、上からのスクロール量が100px以下になった時に点滅が起こり表示されたままになってしまう。

該当のソースコード

html

1<!doctype html> 2<html> 3<head></head> 4 5<body> 6<?php require_once('header.php') ?> 7 8 <section id="MAIN"> 9 <div class="mainview"> 10 <div class="main_text"></div> 11 <a href="#about"><span></span></a> 12 </div><!--end mainview--> 13 <div id="about"> 14 <div class="title_area"></div> 15 <div class="about_cont"></div><!--end about_cont--> 16 </div> 17 <div id="totop"> 18 <a href="/"><img src="img/btn_top.png" alt="TOPへ戻る"></a> 19 </div><!--end totop--> 20 </section><!--end MAIN--> 21 22<?php require_once('footer.php') ?> 23</body> 24</html>

js

1 $(function() { 2 var topBtn = $('#totop'); 3 topBtn.hide(); 4 5 //スクロールが100に達したらボタン表示 6 $(window).scroll(function () { 7 if ($(this).scrollTop() > 100) { 8 topBtn.fadeIn("slow"); 9 } 10 else { 11 topBtn.fadeOut("slow"); 12 } 13 }); 14 15 $(window).scroll(function(ev) { 16 var $window = $(ev.currentTarget), 17 height = $window.height(), 18 scrollTop = $window.scrollTop(), 19 documentHeight = $(document).height(); 20 if (documentHeight === height + scrollTop) { 21 // 一番下のときの処理 22 topBtn.fadeOut("slow"); 23 } else { 24 topBtn.fadeIn("slow"); 25 } 26 }); 27 }); 28

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

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

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

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

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

namda

2018/08/03 02:22

HTMLのソースも添えてください。
退会済みユーザー

退会済みユーザー

2018/08/03 02:30

先ほど追加いたしました。 よろしくお願いいたします。
guest

回答3

0

ん〜…もう少しjQueryに関して勉強しないとダメそう。
コードを書くのはあくまでも質問者さん自身で、それ以上はクラウドワークスにでも行けって低評価されちゃうから頑張って。

今回の悪い所は$(window).scroll(fn)topBtn.fadeOut("slow")の挙動をよく知らない事だから、
これに関しては解説していこう。

$(window).scroll(fn)の挙動

結論: 2つ登録したら2つとも実行されるよ。

JSはシングルスレッドで動作するから、一つのJSコードが走っている場合は、他のコードは一切動作出来ない。
でもブラウザってマウスを動かしながらスクロールしたり、同時並行で色んな動作して欲しいよね?

それに対応するために、JSは「イベント駆動」という思想を取り入れてる。
ブラウザはイベントという棚を用意してくれてて、ここにやりたい事を関数として設置してねというルールを設けている。
$(window).scroll(fn)はページ全体のスクロールが行われた時用のイベントにやりたい事を指定する文。

今回の質問文はこの$(window).scroll(fn)を2つ設置してるね。
こういう書き方すると、jQueryは基本的に登録順に逐次実行してくれる。

topBtn.fadeOut("slow")

結論: これは非同期処理なので、JSの実行はこの行では停止されない。

JSはシングルスレッド動作ってのが根本にあるんだけど、
どうやってフェードアウトを実現しているかというと、CSSプロパティのOpacityを0.01刻みにslowなので2秒間全体を使って等間隔で減らすように実装してるんだよ。(なお数字は適当)

しかしJSはシングルスレッドなのでslowの2秒間まるっと動作を止めるわけには行かない。
setTimeout(fn, 17);という機能を使って、17ミリ秒おきに実行してねというお願いを発行しつつ、休み休み実行する。
つまり、topBtn.fadeOut("slow")の行自身の実行は一瞬で終わる。


この2つを組み合わせるとどうなるか?

$(window).scroll(fn)を2つ登録すると、スクロールの度に実行する。
topBtn.fadeOut("slow")は非同期実行の登録処理でしかないので、
この行自体は一瞬で動作を完了し、その後の2秒間は自動的にCSSのOpacity値の変更することになる。

従って、質問文のコードを実行するとtopBtn.fadeOut("slow")topBtn.fadeIn("slow")がほぼ同時に開始されて点滅されているように見える。
質問文の状況に近いんじゃないかな?


じゃあどうすればいいか?
とりあえず$(window).scroll(fn)を一つにまとめて、
if 〜 else if 〜 ifという風に3つの条件分岐を記述するべきだろうね。

質問文からの2つの条件を加味して適当に設定するとこんな感じになりそうだね。

  • ページトップから100pxは非表示
  • ページボトムから100pxは非表示
  • それ以外は表示

・スクロールを一番下まで行った時にはボタンを非表示にして、上にスクロールをした時には再度ボタンを表示させたい

下までスクロールしたらページトップに戻りたいと思うんだけど、
なんでボタン消えちゃうの?UX的にダメじゃね?感が出てる気がする……

投稿2018/08/03 02:31

miyabi-sun

総合スコア21158

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

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

退会済みユーザー

退会済みユーザー

2018/08/03 02:39

細かいご教授ありがとうございます。 まだまだ勉強不足ですね… 頑張って覚えて行こうと思います。  自分もなぜ一番下に行った時にボタンを消すのかよく分からないんですが、クライアントさんの方の指示で消して欲しいとの事でしたので…  一度教えていただいた条件分岐でやってみたいと思います。 ありがとうございます!
退会済みユーザー

退会済みユーザー

2018/08/03 03:03

miyabi-sun さん デザインにもよりますが、ページトップボタンがフッターの文字に被ったりで消すことは少ないくないです。 フッターまで来てページトップボタンが有るとフッター内のリンク導線をクリックしないでトップに戻り離脱しないためにも消すことがあります。
guest

0

まずボタンの表示非表示を切り替えるための条件を整理してみるといいかもしれません。
今回の場合3つの状態が存在するのではないでしょうか?
1、スクロール量が100px以下の状態
2、スクロールが一番下にいる状態
3、それ以外の状態

1と2のときは非表示、3のときは表示となると思いますが、
それぞれ
1→2
2→3
3→2
2→1
というふうに状態が変化しますよね。
変化したときに1度だけ、その状態に応じでfadeIn,fadeOutをするとこで解決できそうです。

投稿2018/08/03 02:10

keisukeh

総合スコア657

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

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

退会済みユーザー

退会済みユーザー

2018/08/03 02:17

早急なお答えありがとうございます!  早速条件の方を見直してみて一度やってみたいと思います。
guest

0

ベストアンサー

2つ目のwindow.scrollイベントの中身がごちゃごちゃしていたのでまとめてみました!
window.scrollイベントは1つにまとめちゃったほうが良いですよ。

サンプルを作成したのでご確認ください。
動くサンプル

投稿2018/08/03 02:37

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2018/08/03 02:52

とてもわかりやすくコードまで記述をいただきありがとうございます!  思い通りの動きを実装することが出来ました。 window.scrollイベントがぶつかって点滅する自体になっていたのですね…  もっと勉強して行きたいと思います。 ありがとうございます!
退会済みユーザー

退会済みユーザー

2018/08/03 03:23

先ほどはありがとうございました!  上記のコードでPC版のクロームでは大丈夫でしたのですが、iOSのsafariでは一番下に行った時(上下のメニューバーが収縮してる状態)の時には消えない時には何かあるのでしょうか?
退会済みユーザー

退会済みユーザー

2018/08/03 03:40 編集

おそらくIOSのsafariって言うよりスマホ全般で消えない感じかな??と思っております。 スクロールイベントはスクロールする度にイベントが発生しているということは既に解っていただいていると思います。 ということは?? スマホで上下にメニューバーが出たときに下記の計算にずれが生じます。 ということは?? 上下のメニュー分(高さ)のずれを計算に入れれば解決します。 今は「ページの最下部」に到達した時にボタンが消えるようになっています。 そうではなくて「ページの最下部 + 上下のメニュー分の高さ」に到達した時にボタンが消えるようにすれば良いと思いますよ。 var documentHeight = $(document).innerHeight(); console.log('documentHeight:', documentHeight) // ウィンドウの高さを取得 var windowHeight = $(window).innerHeight(); console.log('windowHeight:', windowHeight); // ページの1番下を取得 var pageBottom = documentHeight - windowHeight; console.log('pageBottom:', pageBottom); /* ページ最下部がウィンドウトップと同じ位置あるいはそれ以下の時 ここの条件が通らないとページトップボタンが消えません。 */ if (pageBottom <= windowTop) { console.log('page最下部に到達しました!'); topBtn.fadeOut("slow"); }
退会済みユーザー

退会済みユーザー

2018/08/03 05:36

なるほど。 そうですよね。 メニュー分の高さを足したら消えると言うことですよね!  なので、 if ((pageBottom + 100) <= (windowTop + 100)) { topBtn.fadeOut("slow"); } と言うことになるのでしょうか?
退会済みユーザー

退会済みユーザー

2018/08/03 05:40 編集

それだと結果が変わらなくないですか?? スマホに関しては実機でデバッグをしながらではないと正確のことは言えません。 実際にスマホで確認しながらデバッグを進めてみてください。
退会済みユーザー

退会済みユーザー

2018/08/03 07:10

細かくありがとうございます! やってみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問