🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

2回答

1213閲覧

クリックイベントであれば出来るのにスクロールイベントにした途端、いい加減な挙動になる

annaPanda

総合スコア130

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2020/02/14 07:26

スクロールしていって見え始めたら0から高速でカウントアップして、htmlのテキストに入っている数字になったら止まるビューが作りたいです。

手始めにクリックしたらカウントアップが始まり600になったら止まるようにはできました。

html

1<!DOCTYPE html> 2<html> 3<head> 4 <meta charset="utf-8"> 5 <link rel="stylesheet" href="css/reset.css"> 6 <link rel="stylesheet" href="css/stylesheet.css"> 7 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> 8 <script src="main.js"></script> 9</head> 10<body> 11 <div class="upNumber">600</div> 12</body> 13</html>

css

1body{ 2 height: 2000px; 3 padding: 150px; 4} 5.upNumber{ 6 margin-top: 1500px; 7 font-size: 100px; 8}

js

1$(function () { 2 let finalNumber = $(".upNumber").html(); 3 $(".upNumber").html(0); 4 let totalTime = 5000; 5 let oneUpTime = totalTime / finalNumber 6 $(".upNumber").click( 7 function () { 8 let number = 0; 9 let upNumber = setInterval(function(){ 10 $(".upNumber").html(number); 11 number++ 12 if (number > finalNumber) { 13 clearInterval(upNumber); 14 } 15 } , oneUpTime); 16 } 17 ) 18});

動画のリンクを載せます。  

https://gyazo.com/6ff45be154295725b2b24c5aad47db12

これは思った挙動です。

しかし、これをクリックイベントでなく、スクロールイベントにした途端600をちょっと超えたいい加減な動きになります。

js

1$(function () { 2 // スクロールに関する基本設定 3 let scrollMinus = 140; 4 let scrollPoint; 5 let upNumberHeight = $(".upNumber").offset().top; 6 // カウントアップに関する基本設定 7 let finalNumber = $(".upNumber").html(); 8 $(".upNumber").html(0); 9 let totalTime = 5000; 10 let oneUpTime = totalTime / finalNumber 11 let number = 0; 12 13 $(window).scroll(function () { 14 let scrollTop = $(this).scrollTop(); 15 let scrollBtm = scrollTop + $(this).height(); 16 scrollPoint = scrollBtm - scrollMinus; 17 if (scrollPoint > upNumberHeight && number < finalNumber) { 18 let upNumber = setInterval(function () { 19 $(".upNumber").html(number); 20 number++ 21 if (number > finalNumber) { 22 clearInterval(upNumber); 23 } 24 }, oneUpTime); 25 } 26 }) 27});

動画のリンクを載せます。   

https://gyazo.com/0527abca76b830882ecc71c1f3cf1297

試しにsetIntervalの処理をゆっくりにしてみると、

js

1let upNumber = setInterval(function () { 2 $(".upNumber").html(number); 3 number++ 4 if (number > finalNumber) { 5 clearInterval(upNumber); 6 } 7}, 1000);

よくわからないつっかかりを抱えます。

動画のリンクを載せます。

https://gyazo.com/233a106d896541bf133de07d9ac8dc41

この原因・対策がわかる方いらっしゃいますでしょうか?

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

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

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

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

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

guest

回答2

0

$(window).scrollの中に書いたコードは、スクロールが行われるたびに毎回実行されます。

setInterval自体が複数登録されてしまって、意図しない動作になっているように思われます。

投稿2020/02/14 07:31

maisumakun

総合スコア145963

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

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

annaPanda

2020/02/14 09:10

ご回答ありがとうございました。 今回は具体的な代替案をだしてくださった方をベストアンサーにさせていただきました。
guest

0

ベストアンサー

js

1 upNumber; 2 if (scrollPoint > upNumberHeight && number < finalNumber) { 3 let upNumber = setInterval(function () { 4 if (number > finalNumber) { 5 clearInterval(upNumber); 6 return; 7 } 8 $(".upNumber").html(number); 9 number++; 10 }, oneUpTime);

スクロールのたびにsetInterval()が呼ばれているのが原因です。
なので、finalNumberを超えていたら、カウンタに触る前に関数を脱出するように書き替えました。

投稿2020/02/14 07:40

Lhankor_Mhy

総合スコア36928

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

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

annaPanda

2020/02/14 08:10

回答ありがとうございます。 今、書いてくださったコードを ``` if (scrollPoint > upNumberHeight && number < finalNumber) { let upNumber = setInterval(function () { $(".upNumber").html(number); number++ if (number > finalNumber) { clearInterval(upNumber); } }, oneUpTime); ``` と置き換えたところ、 upNumberは定義されてないと言われたので、 試しに消してみたら、なぜか思った挙動になりました。 そうすると、clearIntervalの入ったif文とnumberをテキストに入れる文とnumberに1足す文を入れ替えているだけに見え、スクロールのたびにsetIntervalなのは変わらないような気がするのですが、意図されたことと違いますか?
Lhankor_Mhy

2020/02/14 08:19

あ、余分な1行がありましたね、失礼しました。 > スクロールのたびにsetIntervalなのは変わらないような気がする 正にその通りです。もちろん、条件文を setInterval に前置してそれ自体を動作させない方法もアリかと思います。 このようなバグ取り質問の場合、他の部分への影響がわからないので、なるべく元のコードに手を加えない回答をすることにしています。なので、お気に召さなければどんどん変更していただいて構いませんよ。
annaPanda

2020/02/14 09:07

なるほどありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問