• 締切済み

スライドショーの再生ボタンがうまくいきません

https://okwave.jp/qa/q9320398.html の続き スライドショーの再生ボタンがうまくいきません 一度止めてから再度再生を押しても再生が再開されません。 何度も恐縮ですが理由がわかりますか? var it; let iterative = ()=> { it = setTimeout(myChange , 5000); } iterative(); let stoppingNow; const pauseBtn = document.getElementById('js-pause-btn'); pauseBtn.addEventListener('click', ()=> { clearTimeout(it); let stoppingNow = true; }); const playBtn = document.getElementById('js-play-btn'); if(stoppingNow === true) { playBtn.addEventListener('click', ()=> { iterative(); stoppingNow = false; });

みんなの回答

回答No.10

>このスライドショーの式などを全体的に囲っている即時関数の中に >(()=> { >let stoppingNow = false; >のように行っても問題なく作動します。 >グローバル変数でないと宣言した変数は、ベントリスナーないであろうがページ読み込み字であろうが処理が終わると消えると思ったのですがなぜうまくいくのでしょうか? 原因はJavaScriptのバグかな?としか思いつきません。 これを新規記事で投稿して他の方々に聞いてみては如何でしょうか。

htmlcss123
質問者

お礼

やっぱり、グローバル以外でページ読み込み後、変数が消えずに残り続けるのは、仕様上おかしいのですね。 >>>> >playBtn.addEventListener('click', ()=> { >iterative(); >stoppingNow = false; >alert("playBtn:stoppingNow = "+stoppingNow); >}); 上記はクリックしたときにだけ実行されるのでページの読み込み時は何のかかわりもないと思っていたのですが、確かに登録する作業なので、 読み込み時にifがfalseなことによって実行されないと登録されないので、 その後クリックしても登録されていないものは決して実行されないので、 いくらクリックしても何も実行されないという事なのですね。 上記の認識は正しいのですね。

回答No.9

>ただ >クリック時には、このifは意味をなさないのでなぜ実行できなかったのでしょうか? >const playBtn = document.getElementById('js-play-btn'); >if(stoppingNow === true) { >playBtn.addEventListener('click', ()=> { >iterative(); >stoppingNow = false; >alert("playBtn:stoppingNow = "+stoppingNow); >}); 最初から考えて下さい、「stoppingNow = false」で「playBtn.addEventListener(~」がスルーされ、下記の内容がイベントリスナーに登録されません。 イベントリスナーに登録されてないのだから、イベントが発生しても、それらは実行されません。 >'click', ()=> { >iterative(); >stoppingNow = false; >alert("playBtn:stoppingNow = "+stoppingNow); >} >このスライドショーの式などを全体的に囲っている即時関数の中に >(()=> { >let stoppingNow = false; >のように行っても問題なく作動します。 >グローバル変数でないと宣言した変数は、ベントリスナーないであろうがページ読み込み字であろうが処理が終わると消えると思ったのですがなぜうまくいくのでしょうか? プログラムをチャント保存していましたか?、プログラムがチャント保存されているのを確認後、ブラウザーでページの再読み込みを何度か試行してみて下さい。

htmlcss123
質問者

お礼

>playBtn.addEventListener('click', ()=> { >iterative(); >stoppingNow = false; >alert("playBtn:stoppingNow = "+stoppingNow); >}); 上記はクリックしたときにだけ実行されるのでページの読み込み時は何のかかわりもないと思っていたのですが、確かに登録する作業なので、 読み込み時にifがfalseなことによって実行されないと登録されないので、 その後クリックしても登録されていないものは決して実行されないので、 いくらクリックしても何も実行されないという事なのですね。

htmlcss123
質問者

補足

また (()=> { let stoppingNow = false; こちらの件ですがやはり再度確認しても上記のようにカプセル化のための即時関数内でもやはりうまくいっています。 試しに削除したところplayできなくなったので間違いないと思います。

回答No.8

>回答No.7 amanojaku1 >↑良く見てみるとif文の位置が変です、下記のように変更してみて下さい。 > >const playBtn = document.getElementById('js-play-btn'); >playBtn.addEventListener('click', ()=> { >if(stoppingNow === true) { >iterative(); >stoppingNow = false; >alert("playBtn:stoppingNow = "+stoppingNow); >} >}); ←★この辺 リスナー内に"}"(終わりブレイス(終わり波括弧))を1つ増やしているので、「←★この辺」の近くの"}"(終わりブレイス(終わり波括弧))を1つ減らす必要があると思われます。

htmlcss123
質問者

お礼

おかげさまでうまくいっているので結果に問題はありません。 下記の部分だけが疑問として残りました 恐らくイベントリスナーの外のifがあったので、 読み込文字にだけifを実行されたが、真ではないので、falseになり、そのままスルーされてていて意味をなさなかったというのはわかりました。 ただ クリック時には、このifは意味をなさないのでなぜ実行できなかったのでしょうか? またカプセル化したいので このスライドショーの式などを全体的に囲っている即時関数の中に (()=> { let stoppingNow = false; のように行っても問題なく作動します。 グローバル変数でないと宣言した変数は、ベントリスナーないであろうがページ読み込み字であろうが処理が終わると消えると思ったのですがなぜうまくいくのでしょうか?

回答No.7

>const playBtn = document.getElementById('js-play-btn'); >if(stoppingNow === true) { >playBtn.addEventListener('click', ()=> { >iterative(); >stoppingNow = false; >alert("playBtn:stoppingNow = "+stoppingNow); >}); ↑良く見てみるとif文の位置が変です、下記のように変更してみて下さい。 const playBtn = document.getElementById('js-play-btn'); playBtn.addEventListener('click', ()=> { if(stoppingNow === true) { iterative(); stoppingNow = false; alert("playBtn:stoppingNow = "+stoppingNow); } });

htmlcss123
質問者

お礼

ありがとうございました。 それが原因でした。 恐らくイベントリスナーの外のifがあったので、 読み込文字にだけifを実行されたが、真ではないので、falseになり、そのままスルーされてていて意味をなさなかったというのはわかりました。 ただ クリック時には、このifは意味をなさないのでなぜ実行できなかったのでしょうか?

回答No.6

デバッグに「alert(~);」を使って見て下さい。 下記のようにして、ボタンのクリック時に「alert(~);」が表示されるか、チェックしてみて下さい(もし予想が正しければ「setTimeout(~)」、「clearTimeout(~)」に問題があるかもしれません)。 グローバルに let stoppingNow = false; カプセル化の即時関数の中に const pauseBtn = document.getElementById('js-pause-btn'); pauseBtn.addEventListener('click', ()=> { clearTimeout(it); stoppingNow = true; alert("pauseBtn:stoppingNow = "+stoppingNow); }); const playBtn = document.getElementById('js-play-btn'); if(stoppingNow === true) { playBtn.addEventListener('click', ()=> { iterative(); stoppingNow = false; alert("playBtn:stoppingNow = "+stoppingNow); });

htmlcss123
質問者

お礼

行ってみました。 pauseボタンはtrue startボタンは無反応でした。 やはりtrueの入った変数がイベントリスナーが終了するとともに、 無くなってしまっているのではないでしょうか? ただなぜグローバルに変数の宣言をしたのになくなっているのかが謎です。

回答No.5

>const pauseBtn = document.getElementById('js-pause-btn'); >pauseBtn.addEventListener('click', ()=> { >clearTimeout(it); >let stoppingNow = true; >}); ↑ここで「stoppingNow」をローカル宣言しているのが原因かと思われます。 >スライドショーの再生ボタンがうまくいきません >一度止めてから再度再生を押しても再生が再開されません。 >何度も恐縮ですが理由がわかりますか? そうすると、なぜ一度目は再生できるのかが疑問ですが…、もしかして(再生ボタンを押さなくても)ページ表示時に自動的に再生してますか?、その場合は「let stoppingNow = true;」の設定値は「true」ではなく「false」に設定して下さい。 とりあえず、下記のように変更してみて下さい。 var it; let iterative = ()=> { it = setTimeout(myChange , 5000); } iterative(); let stoppingNow = true; // ←もし(再生ボタンを押さなくても)ページ表示時に自動的に再生している場合は ここは「false」に設定して下さい。 const pauseBtn = document.getElementById('js-pause-btn'); pauseBtn.addEventListener('click', ()=> { clearTimeout(it); stoppingNow = true; }); const playBtn = document.getElementById('js-play-btn'); if(stoppingNow === true) { playBtn.addEventListener('click', ()=> { iterative(); stoppingNow = false; });

htmlcss123
質問者

お礼

>>> そうすると、なぜ一度目は再生できるのかが疑問ですが…、もしかして(再生ボタンを押さなくても)ページ表示時に自動的に再生してますか?、その場合は「let stoppingNow = true;」の設定値は「true」ではなく「false」に設定して下さい。 仰る通りです。 確かに始めは止まっていないのでfalseでないとおかしいですね。 停止を押したときにfalseにすべきですね。 グローバルに let stoppingNow = false; カプセル化の即時関数の中に const pauseBtn = document.getElementById('js-pause-btn'); pauseBtn.addEventListener('click', ()=> { clearTimeout(it); stoppingNow = true; }); const playBtn = document.getElementById('js-play-btn'); if(stoppingNow === true) { playBtn.addEventListener('click', ()=> { iterative(); stoppingNow = false; }); という形にしたのですがやはり、playボタンを押しても実行されていないようです。 恐らくpauseボタンを押してtrueにはなっているのですが、pauseボタンが終了したと同時に、 stoppingNow = true;がなくなってしまっているのではと思います。

  • doraneko66
  • ベストアンサー率11% (535/4742)
回答No.4

const pauseBtn = document.getElementById('js-pause-btn'); const playBtn = document.getElementById('js-play-btn'); hogehoge(); pauseBtn.addEventListener('click', ()=> { clearTimeout(it); hogehoge(stoppingNow); }); function hogehoge(stoppingNow){ if(stoppingNow === true){ playBtn.addEventListener('click', ()=> { iterative(); }); stoppingNow = false; }else{ playBtn. removeEventListener('click', ()=> { //ボタンの色変えるとか }); stoppingNow = true; } } とか

  • doraneko66
  • ベストアンサー率11% (535/4742)
回答No.3

再生ボタンをファンクションにして 停止ボタンの中に再生ファンクション置いて 引数入れて判定する。とか さらに再生ボタンを押したら、クリックをoffさせるのはいかがでしょうか。

  • doraneko66
  • ベストアンサー率11% (535/4742)
回答No.2

stoppingNowは、どこかのメソッドに入れる値ですか?

  • doraneko66
  • ベストアンサー率11% (535/4742)
回答No.1

これ多分、エラー出てないですか? if文の場所おかしくないですか? そもそもclearTimeoutしているのにif文いる?

htmlcss123
質問者

お礼

ランタイムエラーは出ていません ifは停止ボタンを押した時のみ再生ボタンを押せるようにしているからです。

関連するQ&A

  • アロー関数で変数に入れて名前のある関数にする

    JSでsetTimeoutでのスライドショーの停止、再生がうまくいきません。 http://codepen.io/anon/pen/RVNgLr 問題なく動いているので、停止再生の部分以外は間違えがないと思うのですが、 停止再生の部分に問題はありますでしょうか? 抜粋しておきました。 let iterative = ()=> { setTimeout(myChange , 5000); // } const pauseBtn = document.getElementById('js-pause-btn'); pauseBtn.addEventListener('click', ()=> { clearTimeout(iterative); }); 停止は下記でできるがこれですと名前のある関数にできないので再度動かすことができないのです。 let iterative = { setTimeout(myChange , 5000); // } pauseBtn.addEventListener('click', ()=> { clearTimeout(iterative); }); const playBtn = document.getElementById('js-play-btn'); playBtn.addEventListener('click', ()=> { iterative(); }); pauseBtn.addEventListener('click', ()=> { clearTimeout(iterative); }); iterative();はiterativeという名前の関数を作らないと実行できないので、停止できない理由はわかっているのですが、アロー関数で変数に入れて名前のある関数にすることができないのでどうすれば両方とも実現できるのかわかりません。

  • グローバル変数以外も変数は残り続ける?

    https://okwave.jp/qa/q9323518.html の続き var stoppingNow = false; がグローバル変数になっていないので仕様上はページ読み込み時に実行されて処理が終わった瞬間に この変数は削除されて使えなくなると聞いたのですが、 なぜかpauseBtnを押した後に、playBtnを押すと問題なく使えてしまいます。 グローバルにない変数は、stoppingNow = true;を実行してもそんな変数もうないとなるはずなのですよね? それともグローバルにない変数も残っていて、代入の処理よりも上、ないしは親のスコープにあれば使えるのが仕様なのですか? (function () { var stoppingNow = false; var pauseBtn = document.getElementById('js-pause-btn'); pauseBtn.addEventListener('click', function () { clearTimeout(it); stoppingNow = true; }); var playBtn = document.getElementById('js-play-btn'); playBtn.addEventListener('click', function () { if (stoppingNow === true) { iterative(); stoppingNow = false; } }); } myChange(); })();

  • 他の関数内にあるsetinertvalを参照できな

    clearInterval(timer0);が他の関数内にあるsetinertvalを参照できない。 エラーになってしまいます。 let startSlot = (()=> { let timer0 = setInterval(() => { 内容 }, interval); })(); // stopSlot let stopSlot = (()=> { const stop0 = document.getElementById('stop0'); const stop1 = document.getElementById('stop1'); stop0.addEventListener('click', ()=> { clearInterval(timer0); }); })(); 勝手にカプセル化してしまう スコープの問題に非常に悩むのですがどう対処しますか? let iterative = { setTimeout(myChange , 5000); // } とした場合ちゃんと止まっていますのでスライドショーに問題はないです 停止は上記でできるがこれですと名前のある関数にできないので再度動かすことができないのです。 var playBtn = document.getElementById('js-play-btn'); playBtn.addEventListener('click', function () { _iterative(); }); が変数に代入しただけではできないですよね – よい回答を頂けないので、いろいろな所で聞いています。

  • 他の関数内にあるsetinertvalを参照できな

    clearInterval(timer0);が他の関数内にあるsetinertvalを参照できない。 エラーになってしまいます。 let startSlot = (()=> { let timer0 = setInterval(() => { 内容 }, interval); })(); // stopSlot let stopSlot = (()=> { const stop0 = document.getElementById('stop0'); const stop1 = document.getElementById('stop1'); stop0.addEventListener('click', ()=> { clearInterval(timer0); }); })(); 勝手にカプセル化してしまう スコープの問題に非常に悩むのですがどう対処しますか? よい回答を頂けないので、いろいろな所で聞いています。

  • FLASH/一定時間停止後、再生されるscript

    flash CS4/ActionScript3.0にてサイトローテーションバナーを制作しております。 ムービークリップ「btn1_mc」をクリックするとフラッグ「scene1」を再生し、 「btn1_mc」にポインタが乗った時は一定時間停止し、再生されるという動きを作りたいのですが、初心者のため、うまくActionScriptが書けません。 setTimeout関数を使えば良いということはわかったのですが… 下記コードに書き加え、実装する方法を教えていただければ助かります。 よろしくお願いします。 btn1_mc.addEventListener(MouseEvent.CLICK,btn1Click); btn1_mc.addEventListener(MouseEvent.ROLL_OVER,btn1Over); btn1_mc.addEventListener(MouseEvent.ROLL_OUT,btn1Out); btn1_mc.buttonMode=true; function btn1Click(evt:MouseEvent):void{ gotoAndPlay("scene1"); } function btn1Over(evt:MouseEvent):void{ gotoAndStop("scene1"); btn1_mc.gotoAndStop(2); } function btn1Out(evt:MouseEvent):void{ gotoAndPlay("60"); btn1_mc.gotoAndStop(1); }

  • iがクリックごとに増えるようにしたい

    二度目からはvar i = 0;を行わずにiがクリックごとに増えるようにしたいのですが、うまくいきません var firstClick = true; const startBtn = document.getElementById('js'); startBtn.addEventListener('click', ()=> { if(firstClick) { var i = 0; firstClick = false; } ~ stageNumDefault の二度目クリック時に数値が増えていかずNaNになってしまいます。 https://codepen.io/anon/pen/VbPpby に再現しておきました。

  • iがクリックごとに増えるようにしたい

    二度目からはvar i = 0;を行わずにiがクリックごとに増えるようにしたいのですが、うまくいきません var firstClick = true; const startBtn = document.getElementById('js'); startBtn.addEventListener('click', ()=> { if(firstClick) { var i = 0; var firstClick = false; } ~ var firstClick = true;をグローバルに移動してみましたが今度はなぜかundefinedになってしまいます。 なぜイベントリスナー外に出すとundefinedになってしまうのでしょうか? trueを0にしてもやはりundefinedになってしまいます。 またiは繰り返し増えていく数値全般に使うので、同じ変数名が多用されてどうしても被ってしまうのですが、現場ではどう対処しますか? cssだとbemを使って対処しますが。 jsでもtimerI,timer-iなどにするのでしょうか?

  • javascriptであるボタンを押すと他のボタンの表記が変わるというプログラムをつくりたいのですが。

    モと表示された1個のボタンと穴と表示された2個のボタンを用意する。モのボタンをクリックするとそのボタンの法事は穴に変わり、残り2つの穴のどれかがモに変わる。穴のボタンをクリックされても何も変わらないプログラムをつくりたいのです。 最初の状態からモをクリックして他のボタンを変化させることはなんとかできたのですが、そのあと移動したモをおしても同じことをできるようにするのができなくて困ってます。 あと、できたらモを押して2つの穴のどちらかがモにかわるとき穴からモにかわるボタンは左側のもの、とかは決まってないでランダムだとうれしいです>< おねがいします!!! 全然違うかもしれませんが、つくってみたのものっけておきます <html> <head> <title></title> <script type="text/javascript"> var moFlg = true; function func(){ if (moFlg) { document.getElementById("btn01").innerHTML = "穴"; document.getElementById("btn02").innerHTML = "モ"; document.getElementById("btn03").innerHTML = "穴"; moFlg = !moFlg; } else { document.getElementById("btn01").innerHTML = "穴"; document.getElementById("btn02").innerHTML = "穴"; document.getElementById("btn03").innerHTML = "モ"; moFlg = !moFlg; } } </script> </head> <body> <button id="btn01" type="button" " onClick="func()"> モ </button> <button id="btn02" type="button" " onClick=""> 穴 </button> <button id="btn03" type="button" " onClick=""> 穴 </button> </body> </html> ここまでです。 でもできたら<input type ~ button ~ onClick>とかがつかわれているとうれしいです。

  • iPhoneのsafariにて読込出来ない

    iPhoneの一部のアプリのURLコピーにて読込出来ないものがある。 IE、Android、iPhoneのクリップボード読込可能ですが、iPhoneの一部のアプリのURLコピーが読込出来ない。どうすれば良いでしょうか? <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" charset="utf-8"> </head> <body> <button type="button" id="btn">Read</button> <script type="text/javascript"> document.getElementById('btn').addEventListener('click', async () => { const text = await navigator.clipboard.readText(); alert(text); }); </script> </body> </html>

  • クリックして画像を表示JavaScriptについて

    友人がJavaScriptに苦戦しています。 ボタンをクリックすると、画像が表示されるプログラムを作りたいそうです。以下、送られて来たコードです。 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div class="box"><!--attr (DOMのsetAttributeと同じ)--> <script> addEventListener("load",()=>{ document.getElementById("btn").addEventListener("click",()=>{ //$("img").attr("src","./image.jpg"); document.getElementById("aa").style.color = "white"; document.getElementById("img").style.backgroundImage = "./image.jpg"; }); }); </script> <button id="btn">ここをクリックで画像表示</button> <p id="aa">aa</p> <img id="img"> </div> </body> </html> なぜかボタンをクリックしても、画像が表示されません。なぜなのでしょうか?教えて頂きたく思います。