処理を中断させる方法

このQ&Aのポイント
  • 質問文章において、ある条件のときに処理を中断する方法について説明します。
  • 処理の外部の状況を条件にして、処理を中断させる方法について解説します。
  • 特定の条件を満たした場合、処理を中断する方法について詳しく説明します。
回答を見る
  • ベストアンサー

条件により処理を中断させる方法

下記のようなコードで、ある条件のときに処理を中断するという処理を書きたいと思っています。条件はループ処理の中で変化する変数の状態を検知するのではなく、処理の外部の状況を条件にしたいと思っています。 例えば「1秒たっても終わっていなかったら中断」という様にしたいと思っています。 ※最初は「特定のキーが押されたら中断」などというようにしたかったのですが。 しかしうまくいきません…。下記のコードではIE8, FirFox, Chromeすべて駄目でした。とりあえずIE8だけでも、さらに言えばHTA限定でもOKです。 何とかならないものでしょうか?「このような処理は不可能だ」という情報でも、あきらめることができるためありがたいです。 よろしくお願いします。 <html> <input type="button" id="btn"> <script> document.getElementById("btn").onclick = function() { var flg = false; var tid = window.setInterval(function() {flg = true;}, 1000); for (var i = 0; 80000 > i; i++) { if (flg) { window.clearInterval(tid); alert("break"); break; } document.getElementById("btn").value = i; } alert("finish"); }; </script> </html>

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

ビジーループになっているので途中で他の非同期処理が割り込めないために 処理が停止できないのだと思います。 ループ自体を非同期処理にして適度にintervalによるwaitを入れてあげれば 反応するようになりますね。 こんな感じです。 <html> <input type="button" id="btn"> <input type="button" id="stop" value="stop"> <script> document.getElementById("btn").onclick = function() { var flg = false; var i = 0; var timeoutTimer = window.setTimeout(function() {flg = true;}, 1000); document.getElementById("stop").onclick = function() {flg = true;}; var loopInterval = window.setInterval(function() { document.getElementById("btn").value = i; if (flg) { window.clearInterval(loopInterval); alert("break"); return; } i++; if (i >= 80000) { window.clearTimeout(timeoutTimer); window.clearInterval(loopInterval); alert("finish"); return; } }, 1); }; </script> </html> ただ、1ループ毎に1ms以上のwaitが入ってしまうのでループの性能は劣化します。 setIntervalに渡す中身自体を数回で終わるループにして、waitする間隔を調整すれば多少改善するかもしれません。

pringlez
質問者

お礼

今私の書いたコードを振り返るとなぜsetIntervalなのか意味不明ですね。 #var tid = window.setInterval(function() {flg = true;}, 1000); ここには最初は一定間隔ごとにキー入力を検知するコードが入っていました。という言い訳をしておきます…。 教えていただいたコードでは、ビジーループを防ぐためのコツがよくわかりました。元の処理の構成をほぼ変えずに問題を回避しているので勉強になりました。 補足欄に結果を書きました。もともとはループの中に関数を渡してその関数の処理時間の計測をしたかったので、こんなに処理時間が異なってしまうのは困るのですが、画面描画を含む処理をさせた場合にはこちらのほうが本来の姿なのかもしれませんね。 教えていただいたコードを参考にし、画面描画のコストも考慮にいれ、実装を考えてみたいと思います。 大変参考になりました。ありがとうございました。

pringlez
質問者

補足

比較結果 ◎共通条件 ループ回数=1000 タイムアウト処理なし ◎もとのコード 処理時間IE8/FireFox/Chrome:1秒未満 ブラウザへの描画:NG(最後だけしか反映されない) すべてのブラウザで割り込み不可 ◎教えていただいたコード 処理時間IE8:15秒程度 処理時間FireFox:9秒程度 処理時間Chrome:6秒程度 ブラウザへの描画:OK すべてのブラウザで割り込み可 待ち時間とブラウザへの描画を除いた内部の処理で言えば、ほぼ同じはずだと思います。なので1000回のブラウザへの描画だけで14秒もの時間がかかっているのだと思います(IEの場合)。

関連するQ&A

  • 下記コードの実行方法について質問です。

    問題のコードは下記ですが、 bodyタグに onLoad="firstFunc()" と書かずに実行したいのですが、 スマートな方法はないでしょうか? よろしくお願いいたします。 <script type="text/javascript"> function firstFunc(){ var aFunc = document.getElementById('btn'); aFunc.onclick = function(){ alert('りんご'); } } </script> </head> <body onLoad="firstFunc()"> <button id="btn" name="ボタン">getElementByIdでonclickのイベントを追加できる。</button> </body>

  • javascriptの条件文

    スマホにタッチした時の値を取得するスクリプトです。 よくわからないまま作成してますが、ご勘弁下さい。 <script type="text/javascript"> window.document.addEventListener("touchstart", function(event){ event.preventDefault(); var result = document.getElementById("result"); result.innerHTML = "clientX:"+ event.touches[0].clientX+ "<br>" + "clientY:"+ event.touches[0].clientY; }, true); window.document.addEventListener("touchmove", function(event){ event.preventDefault(); var result = document.getElementById("result"); result.innerHTML = "clientX:"+ event.touches[0].clientX+ "<br>" + "clientY:"+ event.touches[0].clientY; }, true); window.document.addEventListener("touchend", function(event){ event.preventDefault(); var result = document.getElementById("result"); result.innerHTML = ""; }, true); ここまでは正常。 値を取得した、Yを下記のようにしたのですが、 500以上になってもロケーションが実行されません。 間違いなく構文が間違っているのですが、数時間格闘したのですが、わからないので すみませんが、教えて頂けると有難いです。 num = event.touches[0].clientY; if (num >= "500") { location.href = "https://www.google.co.jp/"; } </script>

  • Javascriptの関数について

    Internet Explorer の右クリックメニューに登録するスクリプトを作っています。 たとえば、いま表示しているページのURLを表示する場合、 <script type="text/javascript"> var parentWindow = window.menuArguments; var URL = parentWindow.document.URL; window.onload = function() {   kansuu(URL); }; kansuu = function(url) {   alert(url); } </script> ↑は動きます。 また、 var parentWindow = window.menuArguments; var URL = parentWindow.document.URL; window.onload = kansuu(URL); function kansuu(url) {   alert(url); } ↑も動きます。 ところが、 var parentWindow = window.menuArguments; var URL = parentWindow.document.URL; window.onload = kansuu(URL); kansuu = function(url) {   alert(url); } は動きません。 なぜでしょうか? 理由を教えていただけると嬉しいです。 よろしくお願いします。

  • ループ内のaddeventlistner

    javascript初心者です、いろいろ検索したのですがわからず 教えてください。 サンプル <div id="hoge"></div> <script type=application/javascript> window.onload=function () { var html="検索エンジンのビッグ3" var big3= [ { "name":"google", "url":"http://google.com" }, { "name":"yahoo!", "url":"http://yahoo.com" }, { "name":"bing", "url":"http://bing.com" } ]; for (var i = 0, len = big3.length; i < len; i++) { html+= "<br />名前:"+big3[i].name+"<br />";  html+= "URL:"+big3[i].url+"<br />"; html+= '<input type="button" id="btn" value="投票" /><br />' }; document.getElementById("hoge").innerHTML=html; } </script> ----サンプルここまで このように配列をずらずらっと表示させてそれぞれのボタンを押すと、 その時の配列の情報を参照したいのです。 下のコードをボタンのすぐ下に置きましたが、cannot call method addEventListener of nullってエラーでできず、for文の外だと配列情報がとれず、基礎がわかっておらずすみませんが教えてください。 document.getElementById("btn").addEventListener('click',function(){alert("あなたがおしたのは"+big3[i].name)},false);

  • 続き] divの背景画像を、徐々に表示させるには?

    トップページの2つのdivボックスの背景画像を、徐々に表示されるようにするjavascriptを作って頂いたのですが、リピートをやめる方法を御教えいただくのを忘れてしまいました! (http://oshiete1.goo.ne.jp/qa3921804.html) リピートをとめるには、下記ソースをどのようにすればよろしいでしょうか? ------------------------------------------------------------ fade.js ------------------------------------------------------------ var after = 10; // 秒数を指定 var tid1; var tid2; window.onload = function () { fdi2(); tid2=window.setInterval("fdi2()", after*1000); }; function fdi2() { var img1 = document.getElementById("limg"); img1.style.visibility = "visible"; fadeIn("limg", 0); var img2 = document.getElementById("rimg"); img2.style.visibility = "visible"; fadeIn("rimg", 0); } function fadeIn(imgId, opacity) { if (opacity <= 100) { setOpacity(document.getElementById(imgId), opacity); opacity += 10; tid1=window.setTimeout("fadeIn('" + imgId + "'," + opacity + ")", 80); } else { window.clearTimeout(tid1); } } function setOpacity(img, opacity) { img.style.filter = "alpha(opacity:" + opacity + ")"; img.style.KHTMLOpacity = opacity / 100; img.style.MozOpacity = opacity / 100; img.style.opacity = opacity / 100; }

  • 複数ボタンのクリックイベント

    JavaScriptのイベントなのか変数のスコープなのかで質問がございます。 (一番下に全ソースを貼りました。見づらくて申し訳ありません。) htmlに複数の似た名前のボタンがあります。 名前:button_n (n = 0 to 9) 押されたボタンに応じた処理を登録しようと思い、下記を 9個書いたところ 望んだ動きをしました。 document.getElementById('button_'+0).onclick = function() { clicked(0); } document.getElementById('button_'+1).onclick = function() { clicked(1); } ...... document.getElementById('button_'+9).onclick = function() { clicked(9); } これでは芸がないので、添字の部分を変数にし、下記のようにしたところ for (i=0; i<10; i++) {    document.getElementById('button_'+i).onclick = function() { clicked(i); } } どのボタンを押しても動きません。 私の認識、以下です。  ・0~9のイベントは正しく登録されている。  ・しかし、全てがchecked(10)を呼んでいる 質問1  これを回避する方法と、その対処理由を教えて頂きたくお願い致します。   質問2(オプション)  参考になる資料を教えていただければ幸いです。  例)サイ本のどこを読めばいいよ。とか、このURLがわかりやすいよ。等 よろしくお願い致します。 ■ソース <!DOCTYPE html><html lang="ja"> <head><meta charset="utf-8"></head> <body> <h2>所望の動きをする</h2> <input type="button" id="button_0" value="0"> <input type="button" id="button_1" value="1"> <h2>所望の動きをしてくれない</h2> <p></p> <input type="button" id="button_2" value="2"> <input type="button" id="button_3" value="3"> <script> (function() { document.getElementById('button_'+0).onclick = function() { clicked(0); } document.getElementById('button_'+1).onclick = function() { clicked(1); } /* 配列の最後の添字が使われる気がする。 */ for (i=2; i<4; i++) {    document.getElementById('button_'+i).onclick = function() { clicked(i); } } function clicked(n) { var btn = document.getElementById('button_' + n); console.log(btn.value); alert(btn.value); } })(); </script> </body><html>

  • イベントに適切な値が伝わらない

    0から9までidをもつdivを用意して、それぞれクリックしたら そのidを表示したいのですが、なぜかどれをクリックしても 表示されるのは「10」でした。以下のやり方では何がいけないのでしょうか? function sample(){ for(i=0; i<10; i++){ var obj = document.getElementById(i); obj.onclick = function(){ sample_alert(i); }; } } function sample_alert(i){ alert("i="+i); } window.onload = function() { sample(); } for($i=0; $i<10; $i++){ print "<div id=\"{$i}\">{$i}</div><br>\n"; }

  • JSONPを処理するにはどうすればいいですか?

    http://www.baldanders.info/spiegel/remark/archives/000222.shtml このページの下部のサンプルスクリプトを function getjsonp(url){ で囲ってurlを渡してJSONPデータを処理しようとしたのですが、 hundler is not defined とエラーが出てしまいます。 サンプルスクリプトのそのままのコードでは動くのです。 オブジェクト指向がよくわかっていないのでどうすればいいか、識者の方教えてください。 宜しくお願いします。 下記がエラーするスクリプトです。 <script type="text/javascript" src="/js/jsr_class.js"></script> <div id="bookmark"></div> <script type="text/javascript"> var url ='http://del.icio.us/feeds/json/spiegel?callback=hundler'; getjsonp(url); function getjsonp(url){ var oJsr = new JSONscriptRequest(url); oJsr.buildScriptTag(); oJsr.addScriptTag(); function hundler(data) { var ul = document.createElement('ul'); for (var i=0, post; post = data[i]; i++) { var li = document.createElement('li'); var a = document.createElement('a'); a.setAttribute('href', post.u); a.appendChild(document.createTextNode(post.d)); li.appendChild(a); ul.appendChild(li); } document.getElementById('bookmark').appendChild(ul); oJsr.removeScriptTag(); } } </script>

  • FireFoxでブラウザーと閉じる時に特定の処理を実行したいのですが良い方法を教えてください。

    ブラウザーを閉じる時に特定の処理をWebページ内で実行したのですが、FireFoxでは可能でしょうか? IEでは、下記のロジックで対応することが出来ました。 window.onunload=function() { var x=window.event.clientX,y=window.event.clientY; var w=document.body.clientHeight; if (y<0 &(w-5)<x || x<15) { alert('IEを閉じます。'); } }

  • 一定時間処理を中断

    下記のPGを作ろうと思っています。 このような事は出来るのでしょうか? <HTML> <HEAD> <TITLE>フォームとエレメント(配列で指定)</TITLE> <SCRIPT TYPE="text/javascript"> function fnc_1() { document.write("開始"); } function fnc_2() { document.write("終了"); } </SCRIPT> </HEAD> <BODY> <SCRIPT TYPE="text/javascript"> fnc_1(); <<スリープ機能みたいの>> 一定時間処理を中断する fnc_2(); </SCRIPT> </BODY> </HTML> Javaのsleepコマンドみたいなのがあれば教えてください。 お願いします。

専門家に質問してみよう