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

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

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

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

Q&A

解決済

1回答

1424閲覧

JavaScriptでWindow.onloadやsetTimeoutを使うとループしてしまう原因が分からない

meex

総合スコア63

JavaScript

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

0グッド

1クリップ

投稿2022/08/03 23:02

前提

JavaScriptを用いて自社ショッピングサイトの販売情報を取得する拡張機能を作っています。

実現したいこと

  • 繰り返し処理(ループ)してしまう原因を突き止めたい

発生している問題・エラーメッセージ

Window.onloadとSettimeoutを用いてちゃんとページがローディングされたことが確証されてからDOMの収集処理を行うようにしていますが、なぜか1秒おきにループしてしまうのです。

・window.onloadは1回しか動かないことは、ネットで検索して調べました
・SetIntervalはループするが、setTimeoutはループしない認識です
なので、なぜループしてしまうのかが分かりません。

イメージ説明

該当のソースコード

JavaScript

1/** 2 * Initialize 3 */ 4let MYSERVER_HOST_0 = "http://localhost:8030" 5let MYSERVER_HOST_1 = "https://" 6 7let hostName = MYSERVER_HOST_0 8 9 10 11/** 12 * Start the process 13 */ 14window.onload = function(){ 15 console.log("読み込んだよ") 16 17 18 //ちゃんとロード後に動かしたいため、念のためロード連絡後、1秒待つ 19 setTimeout(function(){ 20 console.log("1秒経ちましたので、処理開始します。") 21 22 let colorSizeVariation = document.getElementsByTagName("li") 23 dd(colorSizeVariation) 24 25 for(let i = 0; i < colorSizeVariation.length; ++i){ 26 //dd(colorSizeVariation[i].outerHTML) 27 } 28 29 30 //------------------------------------ 31 //販売状況を通知 32 //------------------------------------ 33 $(function(){ 34 $.ajax({ 35 type: "post", 36 url: hostName + "http://localhost:8030/api/....., 37 data: { 38 "data" : colorSizeVariation 39 }, 40 dataType : "json" 41 }).done(function(data){ 42 console.log(data); 43 dd("3秒後に管理ページに戻ります。"); 44 setTimeout(function(){ 45 alert("デバッグ用アラート:window.location = hostName + "); 46 }, 3000); 47 }).fail(function(XMLHttpRequest, status, e){ 48 //alert(e); 49 console.log("[ERR]: " + e); 50 }); 51 }); 52 53 console.log("END"); 54 }, 1000); 55} 56 57function dd(str){ 58 console.log(str); 59}

補足情報(FW/ツールのバージョンなど)

使用言語:JavaScript(Chrome 拡張機能)

なぜループしてしまうのでしょうか?知見をお持ちの方がおりましたら、ご教授いただければ幸いです。

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

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

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

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

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

maisumakun

2022/08/04 02:17

JavaScriptは単体のファイルに書いていますか?HTMLに書き付けていますか?
meex

2022/08/04 03:04

Chromeの拡張機能として作成しているため、JavaScript単体のファイルに書いております。 構成としては、以下のようになっております。 [パッケージ名] * manifest.js * j query.min.js * 本処理.js
退会済みユーザー

退会済みユーザー

2022/08/04 09:52

質問者さん、回答したのでそれに対するフィードバックを返してください。役に立った/立たなかったぐらいはすぐに返せるのでは? 役に立たなかったならどこがダメかを書くとより期待に近い回答が出てくるかも。とにかく無言は NG です。
guest

回答1

0

ベストアンサー

想像にすぎませんが、jQuery ajax の応答が帰ってきたとき、window.onload が再び発火するとかではないのでしょうか?

その辺りを調べてみてはいかがでしょう。


【追記】

コードの内容を見てみましたが以下の部分が変です。

$(function(){ $.ajax({ type: "post", ・・・ });

$(function(){ ... }); を外してみたらどうなりますか?

・・・と言うだけでは説得力がなさそうなので自分の環境で試してみました。以下のコードで、

function apiHeroesPost2() { var j = { Id: 6, Name: "ガッチャマンの息子" }; var jsonString = JSON.stringify(j); $.ajax({ type: "POST", url: "/api/values", data: jsonString, contentType: "application/json; charset=utf-8" }) .done (function (data) { $('#heroes').empty(); $.each(data, function (key, val) { var str = val.id + ': ' + val.name; $('<li/>', { html: str }).appendTo($('#heroes')); }); setTimeout(function() { window.location.href = "/home/index"; }, 3000); }) .fail (function (jqXHR, textStatus, errorThrown) { $('#heroes').empty(); $('#heroes').text('textStatus: ' + textStatus + ', errorThrown: ' + errorThrown); }) } window.onload = function() { setTimeout(apiHeroesPost2, 1000); }

window.onload の setTimeout(apiHeroesPost2, 1000); で 1 秒後に jQuery ajax で API が呼ばれ、その応答を受けて done のコールバックが呼ばれて以下のように API から帰ってきた data が表示され、

イメージ説明

そのあと、setTimeout(function() { window.location.href = "/home/index"; }, 3000); で home/index 画面に遷移します。

イメージ説明

これが質問者さんが期待する動きだと思いますがいかがですか?


【追記2】

下のコメント欄の 2022/08/05 14:58 の私のコメントで「Chrome のディベロッパーツールを使って、適当なところにブレークポイントを置いてデバックしてみることをお勧めします。後で回答欄にサンプルの画像を貼っておきます」と書いた件です。

//setTimeout(function() { window.location.href = "/home/index"; }, 3000); はコメントアウトして home/index に遷移しないようにしています。

実行してみると、210 行に制御が飛んでくるのは最初だけで、jQuery ajax 要求に対する応答ではそこには制御は飛んでこないのが分かります。

イメージ説明

下はその操作の要求・応答を Fiddler を使ってキャプチャしたものです。#15 は jQuery ajax による要求・応答です。もしその応答を受けて再び window.onload が発火するならば、再度 jQuery ajax に要る要求が出るはずですが、そうはなってないのが分かります。

イメージ説明

投稿2022/08/03 23:58

編集2022/08/05 06:12
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

meex

2022/08/04 11:51

私の拙い表現から、私がやりたいことを察してくださり、本当にありがとうございました! まさにこの処理をしたかったのです。 ちなみに、追記後のご質問にありました「$(function(){を外したらどうか?」という件ですが、試してみたところ外しても変わりませんでした。。 ⇒調べたところ、イベント内でイベントをすると再帰的に呼び出されてしまう現象があるそうなので、仰っていただいたように「jQuery ajax の応答が帰ってきたとき、window.onload が再び発火する」が原因だったのかと感じています。 参考: https://onl.sc/X3gWnQd 迅速なご回答誠にありがとうございました。
退会済みユーザー

退会済みユーザー

2022/08/05 00:50

> 参考: https://onl.sc/X3gWnQd その記事は JavaScript とは関係ない C# の .NET Framework の Windows Forms アプリに関するものです。なので、このスレッドの話とは関係なさそうですが?
meex

2022/08/05 02:44

ご指摘ありがとうございます。他の言語でも起こるということはJavaScriptでも起こるのではないかと考察し、「イベント中のイベント発火は予期せぬ動きになる可能性がある」という広義な意味あいとしては、同様な問題に直面している他の方への参考や解決へのヒントになるかと思い、載せさて頂いた背景となります。もしご不要でしたら当該URLは削除致します。
退会済みユーザー

退会済みユーザー

2022/08/05 05:58

> 「イベント中のイベント発火は予期せぬ動きになる可能性がある」 それは確かにそうなんですが、「参考: https://onl.sc/X3gWnQd 」に書いてあるコードは、普通あり得ないバカげたことをしているとしか言いようがないです。 やってることは (1) button1 クリック ⇒ (2) button1_Click ハンドラで foo() 呼び出し ⇒ (3) foo() で HogeHandler を発火 ⇒ (4) hoge_HogeHandler ハンドラで foo() 呼び出し ⇒ (5) ステップ (3) に戻る・・・と言うように無限ループになってしまいます。 私の最初の回答で「jQuery ajax の応答が帰ってきたとき、window.onload が再び発火する」と書きましたが、少なくとも私が回答に書いたサンプルではそういうことはないです。それが誤解を招いていたらすみませんでした。 Chrome のディベロッパーツールを使って、適当なところにブレークポイントを置いてデバックしてみることをお勧めします。後で回答欄にサンプルの画像を貼っておきます。 他には Fiddler を使って要求・応答をキャプチャしてみるの良いと思います。その画像も後で貼っておきます。 他に、JavaScript のイベントには、.NET アプリのイベントにはない、バブリングというものがありますので、そのあたりも要チェックだと思います。
meex

2022/08/06 02:05

なるほどです、詳細にお教えいただきありがとうございます。正しい意図をくみ取れずこちらこそ申し訳ございませんでした。 Fiddler というものも初知りだったのでDeveloperツールなども活用しながら、JavaScriptの理解を深めていこうと思います。 本当にご丁寧にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問