• 締切済み

他の関数内にある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); }); })(); 勝手にカプセル化してしまう スコープの問題に非常に悩むのですがどう対処しますか? よい回答を頂けないので、いろいろな所で聞いています。

みんなの回答

回答No.5

ついで。 師匠の名言集から1つ 「変更に強く、丈夫な(他者からの影響を受けない)プログラムを心がけなさい。」

回答No.4

#3です >クラスなら、すべての変数がグローバルになる いろいろと勘違いがあるようですが、説明が面倒なので割愛。 -- >スコープの問題に非常に悩む 一つの関数の中に詰め込めば、結果としてその中では変数を参照出きるのだから 実現したいのならそうすれば好い。 結果として1つのスコープの中で扱う変数は多くなる。さらにプログラムも長くなる。 それぞれの変数の関係を考慮するので、コーディングに時間を要する。 現にあなたはそうするだけで良いのに、それを悩んで質問をしている。 >関数とクラスの違いはこれだけ オブジェクト指向っぽい考え方は、可能な限り機能を細分化しておき、それらを継承もしくは組み合わせて複雑なものを構成していく。 細分化されるとプログラムは短くなる。早く作れる。 回答者側にクラスを継承してプログラムを書ける人は沢山いても、それほど複雑な質問はないしあったとしても面倒なので答えない。(質問者がアレな場合が多いし…想像だけどね) ましてやその便利さを伝えきれないし、理解しなくても用が済んでしまうプログラマが多いのでは? 小さくはない(巨大な)プログラムでも書いてみれば?(書いたことはないけれど) その有り難味がわかるのでは? -- >グローバル変数として定義するしかありません この言葉に意地になってしまった。(時間返せ~!と心の中で叫ぶ) -- あと訂正     this.timerId = clearInterval (this.timerId), null; を     this.timerId = (clearInterval (this.timerId), null); に、     doc.addEventListener ('click', this); を     doc.addEventListener ('click', this, false); に。

htmlcss123
質問者

お礼

あれな回答者ww

回答No.3

<!DOCTYPE html> <meta charset="utf-8"> <title>Slot</title> <style> table th { font-size: xx-large } </style> <body> <table border="1">  <tr>   <th>&nbsp;   <th>&nbsp;   <th>&nbsp;  <tr>   <td>    <input type="button" value="Start">   <td>    <input type="button" value="Start">   <td>    <input type="button" value="Start">  <tr>   <td>    <input type="button" value="Stop">   <td>    <input type="button" value="Stop">   <td>    <input type="button" value="Stop"> </table> <script> {  const   randomInt =    function (n = 10) {     return Math.floor (Math.random () * n);    },   disp =    function () {     let no = randomInt ();     this.no = no;     this.view.textContent = no;    },   init =    function () {     let doc = this.start.ownerDocument;     doc.addEventListener ('click', this);     disp.call (this);    };  class Slot {   constructor (view_emt, start_btn, stop_btn) {    this.view = view_emt;    this.start = start_btn;    this.stop = stop_btn;    this.timerId = null;    this.no = null;    init.call (this);   }   startSlot () {    if (! this.timerId)     this.timerId = setInterval (disp.bind (this), 100);   }   stopSlot () {    if (this.timerId)     this.timerId = clearInterval (this.timerId), null;   }   handleEvent ({target}) {    switch (true) {    case this.start === target :     this.startSlot ();     break;    case this.stop === target :     this.stopSlot ();     break;    }   }  }  this.Slot = Slot; } //_________ let  doc = document,  view = doc.querySelectorAll ('tr:first-of-type th'),  start = doc.querySelectorAll ('tr:nth-of-type(2) input'),  stop = doc.querySelectorAll ('tr:nth-of-type(3) input'),  cell = view.length,  ctrls = []; for (let i = 0; i < cell; i += 1)  ctrls.push (new Slot (view[i], start[i], stop[i])); </script>

htmlcss123
質問者

お礼

やはりクラスなら、すべての変数がグローバルになるのでアクセスがどこからでもできるのですね。 関数とクラスの違いはこれだけでしょうか? つまりこれ以外は関数と同じように使えば問題ないでしょうか?

  • t_ohta
  • ベストアンサー率38% (5081/13278)
回答No.2

> そうするとstartSlotという関数の呼び出しによる実行ができないですよね。 できますよ

  • t_ohta
  • ベストアンサー率38% (5081/13278)
回答No.1

timer0 をグローバル変数として定義するしかありません

htmlcss123
質問者

お礼

そうするとstartSlotという関数の呼び出しによる実行ができないですよね。 このような場合は再利用を飽きらめて、同じソースを何度も使うしかないのでしょうあk?

関連するQ&A

  • 他の関数内にある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(); }); が変数に代入しただけではできないですよね – よい回答を頂けないので、いろいろな所で聞いています。

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

    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/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; });

  • バックグラウンドでも動く setInterval

    https://gist.github.com/kawaz/72f61d8389fed0e9d4e7dc9eb01b39c8 setIntervalはブラウザのタブがバックグラウンドで動作しないとのことで動作させるためのサンプルコードが ないかと調べていたところ上記サイトを見つけました。 ただ、その書きっぷりも訳が分らない & 何をやっているのかわからないです。 当方が昔、見たことのあるJavaScriptとはまるで違っていて「そんな書き方あったっけ?」 という感じです。 例えばsuperInterval.jsの下記の部分に出てくる '=>' というのが謎でそれぞれ何を意味しているのでしょうか? とくに3つ目の 「() => cb(...args)」なんていうのが???です const superInterval = (cb, interval=1000, ...args) => { const code = `self.addEventListener('message', msg=>{setInterval(()=>self.postMessage(null), msg.data)})` w.onmessage = () => cb(...args) (superInterval.js) const superInterval = (cb, interval=1000, ...args) => { try { const code = `self.addEventListener('message', msg=>{setInterval(()=>self.postMessage(null), msg.data)})` const w = new Worker(`data:text/javascript;base64,${btoa(code)}`) w.onmessage = () => cb(...args) w.postMessage(interval) return {stop:()=>w.terminate()} } catch(_){ // 実装の問題またはCSPによる拒否などで Worker が使えなければ普通の setInterval を使う const id = setInterval(cb, interval, ...args) return {stop:()=>clearInterval(id)} } } (使い方) { const log = (...args) => console.log(...args) const {stop} = superInterval(log, 500, 1, {a:2}, [3]) setTimeout(stop, 3000) }

  • 再投稿_バックグラウンドで setInterval

    すみません、誤って同様の質問を締め切ってしまったので再投稿させていただきます。 https://gist.github.com/kawaz/72f61d8389fed0e9d4e7dc9eb01b39c8 setIntervalはブラウザのタブがバックグラウンドで動作しないとのことで動作させるためのサンプルコードが ないかと調べていたところ上記サイトを見つけました。 上記サイトでは下記のようなコードが記述されていたのですやっていることがわからなかったのですが どなたか解説して頂けないでしょうか。 大きく下記2点が不明です。 1. const code = `self.addEventListener('message', msg=>{setInterval(()=>self.postMessage(null), msg.data)})` の部分 setIntervalの第一引数に関数定義「()=>self.postMessage(null)」を渡し、第二引数にmsg.data を渡しています。 これはmessageイベントが発生したらsetIntervalで定期的にpostMessageでWorkerにメッセージ(msg.data)を送信する ということなのでしょうか? そしてその処理をWorkerに渡して処理をバックグラウンドで動かすということをやっているのでしょうか? そもそも'message'イベント(メッセージを受信?どこから?)っていつ起こるものなのでしょうか。 2. superIntervalに渡している引数 (使い方)にあるsuperInterval()に渡している引数がよくわからないです。  第二引数で500を渡していながらsuperIntervalの第二引数はinterval=1000となってるし、 その他の引数についても何のためにどういう使い方をしているかわかりますでしょうか? (superInterval.js) const superInterval = (cb, interval=1000, ...args) => { try { const code = `self.addEventListener('message', msg=>{setInterval(()=>self.postMessage(null), msg.data)})` const w = new Worker(`data:text/javascript;base64,${btoa(code)}`) w.onmessage = () => cb(...args) w.postMessage(interval) return {stop:()=>w.terminate()} } catch(_){ // 実装の問題またはCSPによる拒否などで Worker が使えなければ普通の setInterval を使う const id = setInterval(cb, interval, ...args) return {stop:()=>clearInterval(id)} } } (使い方) { const log = (...args) => console.log(...args) const {stop} = superInterval(log, 500, 1, {a:2}, [3]) setTimeout(stop, 3000) }

  • テキスト内容の変化でイベント発生

    下記のようなコードでイベントを発生したいと考えています。 キーボードによる打ち込みではなく、文章をコピー&ペーストすることで 「firstBox2」の表示を消し、「secondBox2」を表示させたいと考えています。 ご教授お願いします。 <input id="target_input" type="text" value="" /> <select id="firstBox2"> <option value="select1">-----</option> <option value="select2">------</option> </select> <select id="secondBox2" style="display:none;"> <option value="select1">午前中</option> <option value="select2">2度目以降の利用</option> </select> <script type="text/javascript"> var timer = null; var input = document.getElementById("target_input"); var prev_val = input.value; input.addEventListener("focus", function(){ window.clearInterval(timer); timer = window.setInterval(function(){ var new_val = input.value; if(prev_val != new_val){ document.getElementById('firstBox2').style.display = "none"; document.getElementById('secondBox2').style.display = ""; }; prev_value = new_value; }, 10); }, false); input.addEventListener("blur", function(){ window.clearInterval(timer); }, false); } </script>

  • ひとつのボタンでタイマーを動かしたり止めたりしたいのですが

    ひとつのボタンでタイマーを動かしたり止めたりしたいのですが こんにちは 趣味でjavascriptをしているものです 以下のサイトから、テトリスのコードをダウンロードしたのですが、 http://java.aimary.com/ このjavascriptの動くhtml内に  gameInterval(ゲーム内のタイマー変数)を 使って、ポーズボタンのようなものを追加したいと思ったのですが、 以下のコードのようにすると、いったん停止したとおもったら、 再びタイマーが呼び出され、何度も押すと、タイムインターバルが 短くなっていきました。 //headに追加 function clear_timer() { var obj = document.getElementById("timer_control"); clearInterval( gameInterval ); obj.detachEvent('onclick', clear_timer); obj.attachEvent('onclick', set_timer ); } function set_timer() { var obj = document.getElementById("timer_control"); obj.detachEvent('onclick', set_timer ); obj.detachEvent('onclick', clear_timer ); gameInterval = window.setInterval("Handle_Interval()", (maxspeed-speed+1)*60); obj.attachEvent( 'onclick', clear_timer ); } //bodyに追加 <div style='position:absolute; left:520px; top:100px;'> <form name='Form1'> <input type="button" id="timer_control" value="pause" onclick="JavaScript:clear_timer();"> </form> </div> おそれいりますが、どなたか、正しい記述の仕方を 教えていただけないでしょうか? よろしくおねがいします。

  • オブジェクトがぶつかった時の処理

    <script type="text/javascript"> <!-- var imgStar ,imgMoon, timer; var dx = 6, dy = 4, x = 40, y = 160; function startMove(){ if (document.getElementById){ imgStar = document.getElementById("star"); imgMoon = document.getElementById("moon"); timer = setInterval("moveImg()",50); } } function moveImg(){ imgStar.style.left = x + "px"; imgStar.style.top = y + "px"; imgMoon.style.left = (440-x) + "px"; imgMoon.style.top = (320-y) + "px"; x = x + dx; y = y + dy; if (x<=40 || x >= 400) dx = -dx; if (y<=40 || y >= 280) dy = -dy; } function stopTimer() { if (window.clearInterval) clearInterval(timer); } //--> </script> 星と月がぶつかると、お互い逆方向にはね返るようにしたいのですが、この場合どうすれば良いでしょうか?

  • 変数の宣言をグローバルにしないと変数の参照が出来ま

    変数の宣言をグローバルにしないと変数の参照が出来ません。 ソース全体はカプセル化のために即時関数で囲っています。 function found内で小数点第三位までで四捨五入するようにする処理が共通なので関数化したのですが、 var gramNumを外で宣言しないと参照できずにgramNumが定義されていないと出てしまい困りました 関数スコープの影響だと思い宣言を外に出したのですが、それでも定義されていないと出て、 最終的にグローバル変数にしてやっとうまくいきました。 スコープは自分より上のスコープの変数は参照できるようですが if(xGramEmptyFlag === true) {ないの式がroundの上にあるvar gramNumを参照する場合、 if分の中にある式の一つ上のスコープなので参照できると思ったのですがなぜできないのでしょうか? varはブロックスコープがないので一つ上ではなく同じスコープにあることになるのでしょうか? ただその場合も同じスコープの変数は参照できるのではないのでしょうか?

  • 画面が遷移したみたいになってしまいます。

    画面ロード後にjavascriptで動的にまたjavascriptタグを表示しています。 以下のjavascriptを組み込んでみたところ、取得したjavascriptを表示したときに画面遷移したみたいになってしまいました。 どうすればきちんと表示されるようになるでしょうか。 <div id="position"></div> <script language="javascript">// <!-- var timer = setInterval("Timer()", 1000); function Timer() { var position = document.getElementById('position'); var script = document.createElement('script'); script.setAttribute('type', 'text/javascript'); script.setAttribute('src', 'http://hogehoge/getjs'); position.appendChild(script); clearInterval(timer); } // --></script> http://hogehoge/getjsからはコンテンツの部品を表示するjavascriptが入っています。

専門家に質問してみよう