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

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

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

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

Q&A

解決済

2回答

1074閲覧

setIntervalを使用して文字をスムーズに横へ移動させたい

hiiro46

総合スコア21

JavaScript

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

0グッド

0クリップ

投稿2021/07/27 10:34

編集2021/07/27 11:17

自作のミュージックプレイヤーを制作しています。
そこで不明な点が現れたので質問します。

下記のコードをご覧ください。

//再生・停止event playbtn.addEventListener("click", () => { let musicpaused = player_box.classList.contains("paused"); musicpaused ? pausedMusic() : playMusic(); });
//停止event定義 function pausedMusic() { if(musicimg.classList.contains("roseReset")){ musicimg.classList.remove("roseReset"); } player_box.classList.remove("paused"); information.classList.remove("leftActive","rightActive"); playicon.setAttribute("class","fas fa-play"); musicimg.classList.remove("rote"); musicimg.classList.add("rosestop"); mainaudio.pause(); };
//再生event定義 function playMusic() { if(musicimg.classList.contains("roseReset")){ musicimg.classList.remove("roseReset"); } player_box.classList.add("paused"); information.classList.add("leftActive"); infoStart(); playicon.setAttribute("class","fas fa-pause"); musicimg.classList.remove("rosestop"); musicimg.classList.add("rote"); mainaudio.play(); };
const infoStart = () => { let stop = setInterval(function () { if(player_box.classList.contains("paused")){ infoEvent(); } },5000); }
//infoEvent定義 function infoEvent () { if(information.classList.contains("leftActive")){ information.classList.remove("leftActive"); information.classList.add("rightActive"); }else{ information.classList.remove("rightActive"); information.classList.add("leftActive"); } };

実際のプレビューは下記のコードペンに記載しています。(一度見ていただけると内容を把握できるかと思います)
CodePen

再生ボタンを押すことで文字がスムーズに繰り返し横へ移動します。
もう一度再生ボタンを押すことでinfoEvent()実装。
しかし実際はスムーズに横へ進まない。

試したこと

//停止event定義 function pausedMusic() { if(musicimg.classList.contains("roseReset")){ musicimg.classList.remove("roseReset"); } player_box.classList.remove("paused"); information.classList.remove("leftActive","rightActive");   infoJudge(); playicon.setAttribute("class","fas fa-play"); musicimg.classList.remove("rote"); musicimg.classList.add("rosestop"); mainaudio.pause(); };
//再生event定義 function playMusic() { if(musicimg.classList.contains("roseReset")){ musicimg.classList.remove("roseReset"); } player_box.classList.add("paused"); information.classList.add("leftActive"); infoJudge(); playicon.setAttribute("class","fas fa-pause"); musicimg.classList.remove("rosestop"); musicimg.classList.add("rote"); mainaudio.play(); };
const infoJudge = () => { let stop = setInterval(function () { if(player_box.classList.contains("paused")){ infoEvent(); }else{ clearInterval(stop); } },5000); }

僕の解釈ではpausedがある間はinfoEvent()続行。
pausedが無い場合は動作キャンセル。
再度、再生ボタンを押すことでinfoEvent()続行。
最初に再生ボタンを押したときのように横へスムーズに移動すると考えていた。
しかし実際は文字が戻ったりして横へスムーズに進まない。

解決したいこと

・playbtnを何回押してもスムーズに文字を横へ移動させたい
・setInterval以外で"文字をスムーズに横へ繰り返し移動する方法"があるのか知りたい

何卒よろしくお願いします。

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

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

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

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

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

guest

回答2

0

自己解決

let Stop; const infoJudge = () => { if(player_box.classList.contains("paused")){ Stop = setInterval(function () { infoEvent(); },5000); } if(!player_box.classList.contains("paused")){ clearInterval(Stop); } }

上記のコードでスムーズに横へ移動することが出来ました!
変数を関数外で記載した。
setInterval内でclearIntervalを記載したことが原因だと思われる。
下記CodePenに全コード記載。
CodePen

投稿2021/07/28 10:42

hiiro46

総合スコア21

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

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

0

(現時点で元々のcodepenのコードが変わっているようですが、質問文のコードに基づいて回答します)

多分修正の必要があるのはこの部分で、

const infoJudge = () => { let stop = setInterval(function () { if(player_box.classList.contains("paused")){ infoEvent(); }else{ clearInterval(stop); } },5000); }

これだと、stopがinfoJudgeのスコープ内にあるので、infoJudgeを呼び出す度にstopの値がリセットされます。
結果、一時停止時に、setIntervalに対応したidのclearIntervalが正しく呼ばれません。
そして、一時停止から再生に戻る度にsetIntervalが重ねて呼ばれることになり、位置の切り替え動作であるinfoEventが本来の想定と異なる(いわばランダムな)間隔で呼ばれ、スクロールが飛び飛びになる動きになります。

一例として 下記のように、スコープをまたいでidを保存する変数を用意し、
一時停止/再生の度にintervalを登録・解放するやり方があるかもしれません。

js

1// infoStart(), infoStop()両方で使用するidを保存する変数 2const stop = { id: null }; 3 4const infoStart = () => { 5 stop.id = setInterval(function () { 6 infoEvent(); 7 },5000); 8} 9 10const infoStop = () => { 11 clearInterval(stop.id); 12 stop.id = null; 13}

diff

1//再生event定義 2function playMusic() { 3~略~ 4 information.classList.add("leftActive"); 5+ infoStart(); 6~略~ 7 mainaudio.play(); 8}; 9 10//停止event定義 11function pausedMusic() { 12~略~ 13 information.classList.remove("leftActive","rightActive"); 14+ infoStop(); 15 playicon.setAttribute("class","fas fa-play"); 16 musicimg.classList.remove("rote"); 17 musicimg.classList.add("rosestop"); 18 mainaudio.pause(); 19};

また、曲送り・曲戻しの際も適切にinfoを停止させるようにします。

diff

1//次曲関数定義 2function nextMusic() { 3~略~ 4 player_box.classList.remove("paused"); 5+ information.classList.remove("leftActive","rightActive"); 6+ infoStop(); 7 musicimg.classList.remove("rote"); 8~略~ 9 mainaudio.pause(); 10 11} 12//前曲関数定義 13function prevMusic() { 14~略~ 15 player_box.classList.remove("paused"); 16+ information.classList.remove("leftActive","rightActive"); 17+ infoStop(); 18~略~ 19 mainaudio.pause(); 20}

全体:codePen

投稿2021/07/27 13:02

編集2021/07/27 14:50
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

hiiro46

2021/07/28 10:45

qnoirさん、回答ありがとうございます! 自己解決しました。 曲送り・曲戻しも修正出来ました。 ありがとうざいます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問